[Libreoffice-commits] core.git: Branch 'private/kohei/calc-shared-string' - 515 commits - afms/ExternalPackage_fontunxafm.mk afms/Makefile afms/Module_afms.mk afms/README afms/UnpackedTarball_afms.mk apache-commons/ExternalPackage_apache_commons_logging.mk apache-commons/ExternalProject_apache_commons_codec.mk apache-commons/ExternalProject_apache_commons_httpclient.mk apache-commons/ExternalProject_apache_commons_lang.mk apache-commons/ExternalProject_apache_commons_logging.mk apache-commons/Makefile apache-commons/Module_apache-commons.mk apache-commons/Package_apache_commons_codec.mk apache-commons/Package_apache_commons_httpclient.mk apache-commons/Package_apache_commons_lang.mk apache-commons/patches apache-commons/README apache-commons/UnpackedTarball_apache_commons_codec.mk apache-commons/UnpackedTarball_apache_commons_httpclient.mk apache-commons/UnpackedTarball_apache_commons_lang.mk apache-commons/UnpackedTarball_apache_commons_logging.mk avmedia/source basctl/source basegfx/sou rce basic/qa basic/source beanshell/bsh-2.0b1-src.patch beanshell/ExternalPackage_beanshell.mk beanshell/ExternalProject_beanshell.mk beanshell/Makefile beanshell/Module_beanshell.mk beanshell/README beanshell/UnpackedTarball_beanshell.mk bin/find-unusedheaders.pl boost/boost_1_44_0-clang-warnings.patch boost/boost_1_44_0-gcc4.8.patch boost/boost_1_44_0-unused-parameters.patch boost/boost.3780.aliasing.patch boost/boost.4100.warnings.patch boost/boost.4510.warnings.patch boost/boost.4713.warnings.patch boost/boost.6142.warnings.patch.1 boost/boost.6369.warnings.patch boost/boost.6397.warnings.patch boost/boost.7551.unusedvars.patch boost/boost.auto_link.patch boost/boost.endian.patch boost/boost.gcc47679.patch boost/boost.libcdr.warnings.patch.1 boost/boost.loplugin.patch boost/boost.std.move.patch boost/boost.transform_width.patch boost/boost.vc2012.patch boost/boost.wdeprecated-auto_ptr.patch.0 boost/boost.wdeprecated-register.patch.0 boost/boost.windows.patch boost/boost. wshadow.patch boost/boost.wundef.patch boost/boost.wuninitialized.patch boost/boost.wunused.patch boost/Makefile boost/Module_boost.mk boost/README boost/StaticLibrary_boostdatetime.mk boost/StaticLibrary_boostsystem.mk boost/StaticLibrary_boostthread.mk boost/UnpackedTarball_boost.mk bridges/test cairo/cairo cairo/ExternalPackage_cairo.mk cairo/ExternalPackage_pixman.mk cairo/ExternalProject_cairo.mk cairo/ExternalProject_pixman.mk cairo/Makefile cairo/Module_cairo.mk cairo/pixman cairo/README cairo/UnpackedTarball_cairo.mk cairo/UnpackedTarball_pixman.mk canvas/source chart2/CppunitTest_chart2_export.mk chart2/CppunitTest_chart2_import.mk chart2/inc chart2/source clucene/configs clucene/Library_clucene.mk clucene/Makefile clucene/Module_clucene.mk clucene/patches clucene/README clucene/UnpackedTarball_clucene.mk comphelper/source config_host/config_features.h.in config_host.mk.in configmgr/CppunitTest_configmgr_unit.mk configmgr/source configure.ac connectivity/inc connect ivity/source connectivity/workben cppcanvas/CppunitTest_cppcanvas_test.mk cppuhelper/source cppunit/android.patch cppunit/disable-dynloading.patch cppunit/ExternalPackage_cppunit.mk cppunit/ExternalProject_cppunit.mk cppunit/ios.patch cppunit/Makefile cppunit/Module_cppunit.mk cppunit/README cppunit/unix.patch cppunit/UnpackedTarball_cppunit.mk cppunit/windows.patch cppunit/wundef.patch ct2n/ConvertTextToNumber-1.3.2-no-license.patch ct2n/ConvertTextToNumber-1.3.2-no-visible-by-default.patch ct2n/description-en-US.txt ct2n/ExternalPackage_ct2n.mk ct2n/Makefile ct2n/Module_ct2n.mk ct2n/README ct2n/UnpackedTarball_ct2n.mk cui/inc cui/source curl/curl-7.26.0_mingw.patch curl/curl-7.26.0_nspr.patch curl/curl-7.26.0.patch curl/curl-7.26.0_strlcat.patch curl/curl-7.26.0_win.patch curl/curl-7.26.0_win-proxy.patch curl/curl-aix.patch curl/curl-android.patch curl/ExternalPackage_curl.mk curl/ExternalProject_curl.mk curl/Makefile curl/Module_curl.mk curl/README curl/UnpackedTarball_cu rl.mk dbaccess/CppunitTest_dbaccess_dialog_save.mk dbaccess/CppunitTest_dbaccess_embeddeddb_performancetest.mk dbaccess/CppunitTest_dbaccess_firebird_test.mk dbaccess/CppunitTest_dbaccess_hsqldb_test.mk dbaccess/CppunitTest_dbaccess_macros_test.mk dbaccess/source desktop/CustomTarget_desktop_unopackages_install.mk desktop/GeneratedPackage_desktop_unopackages_install.mk desktop/inc desktop/Library_sofficeapp.mk desktop/Module_desktop.mk desktop/scripts desktop/source desktop/unx distro-configs/LibreOfficeAndroid.conf distro-configs/LibreOfficeAndroidX86.conf distro-configs/LibreOfficeLinux.conf distro-configs/LibreOfficeMacOSX.conf distro-configs/LibreOfficeOpenBSD.conf distro-configs/LibreOfficeWin32.conf distro-configs/OxygenOfficeLinux.conf distro-configs/OxygenOfficeWin32.conf distro-configs/README download.lst drawinglayer/inc dtrans/source editeng/source epm/epm-3.7.patch epm/ExternalPackage_epm.mk epm/ExternalProject_epm.mk epm/Makefile epm/Module_epm.mk epm/README epm /UnpackedTarball_epm.mk expat/expat-2.1.0.patch expat/expat-winapi.patch expat/ExternalProject_expat.mk expat/Makefile expat/Module_expat.mk expat/README expat/StaticLibrary_expat.mk expat/StaticLibrary_expat_x64.mk expat/UnpackedTarball_expat.mk extensions/source external/afms external/apache-commons external/beanshell external/boost external/cairo external/clucene external/cppunit external/ct2n external/curl external/CustomTarget_jawt.mk external/epm external/expat external/firebird external/fontconfig external/freetype external/glibc external/graphite external/harfbuzz external/hsqldb external/hunspell external/hyphen external/icu external/libatomic_ops external/libpng external/mingw-externals external/Module_external.mk external/msc-externals external/Package_dbghelp.mk external/Package_jawt.mk external/Package_mingw_dlls.mk external/Package_mingw_gccdlls.mk external/Package_msms.mk external/Package_msvc80_dlls.mk external/Package_msvc_dlls.mk external/README external/St aticLibrary_gnu_readdir_r.mk external/UnpackedTarball_glibc.mk extras/source fileaccess/Library_fileacc.mk fileaccess/Makefile fileaccess/Module_fileaccess.mk fileaccess/README fileaccess/source filter/source firebird/ExternalPackage_firebird.mk firebird/ExternalProject_firebird.mk firebird/firebird-c++11.patch.1 firebird/firebird-cygwin-msvc.patch.1 firebird/firebird-icu.patch.1 firebird/firebird-macosx.patch.1 firebird/firebird-rpath.patch.0 firebird/Makefile firebird/Module_firebird.mk firebird/UnpackedTarball_firebird.mk fontconfig/ExternalPackage_fontconfig.mk fontconfig/ExternalProject_fontconfig.mk fontconfig/fontconfig-2.8.0.patch fontconfig/Makefile fontconfig/Module_fontconfig.mk fontconfig/README fontconfig/UnpackedTarball_fontconfig.mk forms/source formula/source fpicker/test framework/inc framework/source freetype/ExternalPackage_freetype.mk freetype/ExternalProject_freetype.mk freetype/freetype-2.4.8.patch freetype/Makefile freetype/Module_freetype.mk freetype/ README freetype/UnpackedTarball_freetype.mk graphite/graphite2.issue1115.patch.1 graphite/graphite2.patch graphite/Makefile graphite/Module_graphite.mk graphite/README graphite/StaticLibrary_graphite.mk graphite/UnpackedTarball_graphite.mk harfbuzz/ExternalProject_harfbuzz.mk harfbuzz/Makefile harfbuzz/Module_harfbuzz.mk harfbuzz/README harfbuzz/UnpackedTarball_harfbuzz.mk helpcontent2 hsqldb/ExternalPackage_hsqldb.mk hsqldb/ExternalProject_hsqldb.mk hsqldb/Makefile hsqldb/Module_hsqldb.mk hsqldb/patches hsqldb/README hsqldb/UnpackedTarball_hsqldb.mk hunspell/ExternalProject_hunspell.mk hunspell/hunspell-1.3.2-compound.patch hunspell/hunspell-1.3.2-literal.patch hunspell/hunspell-1.3.2-nullptr.patch hunspell/hunspell-1.3.2-overflow.patch hunspell/hunspell-android.patch hunspell/hunspell.rhbz918938.patch hunspell/hunspell-solaris.patch hunspell/hunspell-twoaffixcompound.patch hunspell/hunspell-wundef.patch.1 hunspell/Makefile hunspell/Module_hunspell.mk hunspell/README hunspe ll/StaticLibrary_hunspell.mk hunspell/UnpackedTarball_hunspell.mk hyphen/ExternalPackage_hyphen.mk hyphen/ExternalProject_hyphen.mk hyphen/hyphen-android.patch hyphen/hyphen-build.patch hyphen/hyphen-fdo43931.patch hyphen/hyphen-lenwaswrong.patch hyphen/hyphen-rhmin.patch hyphen/Makefile hyphen/Module_hyphen.mk hyphen/README hyphen/StaticLibrary_hyphen.mk hyphen/UnpackedTarball_hyphen.mk i18nlangtag/qa i18nlangtag/source i18npool/Library_localedata_euro.mk i18npool/source icon-themes/galaxy icon-themes/hicontrast icu/ExternalPackage_icu.mk icu/ExternalProject_icu.mk icu/icu4c.10129.wintz.patch icu/icu4c-aix.patch icu/icu4c-android.patch icu/icu4c-buffer-overflow.patch icu/icu4c-build.patch icu/icu4c-macosx.patch icu/icu4c-mkdir.patch icu/icu4c-rpath.patch icu/icu4c-solarisgcc.patch icu/icu4c-warnings.patch icu/icu4c-wchar_t.patch icu/Makefile icu/Module_icu.mk icu/README icu/UnpackedTarball_icu.mk idl/source include/basegfx include/comphelper include/filter include/formula i nclude/helpcompiler include/i18nlangtag include/oox include/osl include/rtl include/sal include/sax include/sfx2 include/svl include/svtools include/svx include/toolkit include/tools include/touch include/unotools include/vcl include/xmloff instsetoo_native/CustomTarget_install.mk instsetoo_native/Module_instsetoo_native.mk instsetoo_native/util ios/experimental ios/.gitignore ios/lo.xcconfig.in ios/MobileLibreOffice ios/qa ios/shared jvmfwk/plugins l10ntools/source libatomic_ops/ExternalPackage_libatomic_ops.mk libatomic_ops/ExternalProject_libatomic_ops.mk libatomic_ops/Makefile libatomic_ops/Module_libatomic_ops.mk libatomic_ops/README libatomic_ops/UnpackedTarball_libatomic_ops.mk libpng/configs libpng/Makefile libpng/Module_libpng.mk libpng/README libpng/StaticLibrary_png.mk libpng/UnpackedTarball_png.mk libvisio/0001-fdo-70480-do-not-crash-reading-malformed-zip.patch libvisio/UnpackedTarball_libvisio.mk libxmlsec/ExternalProject_xmlsec.mk lingucomponent/Library_guessla ng.mk lingucomponent/source lotuswordpro/source Makefile.fetch Makefile.in mdds/0001-Combine-these-two-calls.-There-is-no-reason-why-they.patch mdds/0001-Fix-it-here-too.patch mdds/UnpackedTarball_mdds.mk mysqlc/source neon/Library_neon.mk offapi/com officecfg/Configuration_officecfg.mk officecfg/files.mk officecfg/registry oox/inc oox/Library_oox.mk oox/source postgresql/ExternalProject_postgresql.mk postprocess/CustomTarget_registry.mk postprocess/Rdb_services.mk python3/ExternalPackage_python3.mk python3/ExternalProject_python3.mk readlicense_oo/docs README.cross README.solver reportdesign/inc reportdesign/source RepositoryExternal.mk Repository.mk RepositoryModule_build.mk RepositoryModule_host.mk rsc/source sal/android sal/qa sal/rtl sax/CppunitTest_sax_attributes.mk sax/CppunitTest_sax_parser.mk sax/Library_fastsax.mk sax/Module_sax.mk sax/qa sax/source scaddins/source sc/CppunitTest_sc_annotationobj.mk sc/CppunitTest_sc_annotationshapeobj.mk sc/CppunitTest_sc_annotati onsobj.mk sc/CppunitTest_sc_cellrangeobj.mk sc/CppunitTest_sc_chart_regression_test.mk sc/CppunitTest_sc_databaserangeobj.mk sc/CppunitTest_sc_datapilotfieldobj.mk sc/CppunitTest_sc_datapilottableobj.mk sc/CppunitTest_sc_editfieldobj_cell.mk sc/CppunitTest_sc_editfieldobj_header.mk sc/CppunitTest_sc_filters_test.mk sc/CppunitTest_sc_macros_test.mk sc/CppunitTest_sc_modelobj.mk sc/CppunitTest_sc_namedrangeobj.mk sc/CppunitTest_sc_namedrangesobj.mk sc/CppunitTest_sc_outlineobj.mk sc/CppunitTest_sc_rangelst_test.mk sc/CppunitTest_sc_subsequent_export_test.mk sc/CppunitTest_sc_subsequent_filters_test.mk sc/CppunitTest_sc_tableautoformatfield.mk sc/CppunitTest_sc_tablesheetobj.mk sc/CppunitTest_sc_tablesheetsobj.mk sc/CppunitTest_sc_ucalc.mk sc/inc sc/Library_sc.mk scp2/InstallModule_ooo.mk scp2/InstallModule_sdkoo.mk scp2/InstallModule_smoketest.mk scp2/InstallScript_test.mk scp2/Module_scp2.mk scp2/source sc/qa scripting/source scripting/workben sc/source sd/AllLangResTarget_sd .mk sd/CppunitTest_sd_filters_test.mk sd/CppunitTest_sd_import_tests.mk sdext/Configuration_minimizer.mk sdext/Extension_minimizer.mk sdext/Library_minimizer.mk sdext/Library_PresentationMinimizer.mk sdext/Module_sdext.mk sdext/Rdb_minimizer.mk sdext/source sd/inc sd/qa sd/sdi sd/source sd/uiconfig setup_native/Package_packinfo.mk setup_native/source sfx2/inc sfx2/sdi sfx2/source sfx2/uiconfig shell/source slideshow/inc slideshow/source smoketest/lodownloadtest.py smoketest/losmoketest smoketest/losmoketest.readme smoketest/Module_smoketest.mk smoketest/Package_losmoketest.mk smoketest/Package_smoketestdoc.mk solenv/bin solenv/doc solenv/gbuild sot/source starmath/qa starmath/source svgio/inc svgio/source svl/qa svl/source svtools/inc svtools/source svx/inc svx/source sw/CppunitTest_sw_filters_test.mk sw/CppunitTest_sw_htmlexport.mk sw/CppunitTest_sw_layout_test.mk sw/CppunitTest_sw_macros_test.mk sw/CppunitTest_sw_odfexport.mk sw/CppunitTest_sw_odfimport.mk sw/CppunitTest_s w_ooxmlexport.mk sw/CppunitTest_sw_ooxmlimport.mk sw/CppunitTest_sw_rtfexport.mk sw/CppunitTest_sw_rtfimport.mk sw/CppunitTest_sw_uiwriter.mk sw/CppunitTest_sw_uwriter.mk sw/CppunitTest_sw_ww8export.mk sw/CppunitTest_sw_ww8import.mk sw/inc sw/JunitTest_sw_complex.mk sw/Module_sw.mk sw/qa sw/sdi sw/source sw/uiconfig sw/UIConfig_swriter.mk tools/source ucb/Library_ucb1.mk ucb/source unoidl/source unotools/source unusedcode.easy vcl/android vcl/aqua vcl/coretext vcl/Executable_xid_fullscreen_on_all_monitors.mk vcl/inc vcl/ios vcl/Module_vcl.mk vcl/qa vcl/source vcl/unx vcl/win wizards/Module_wizards.mk wizards/Package_access2base.mk wizards/source writerfilter/inc writerfilter/Library_writerfilter.mk writerfilter/source writerperfect/qa xmlhelp/source xmloff/CppunitTest_xmloff_uxmloff.mk xmloff/inc xmloff/Library_xo.mk xmloff/source xmlsecurity/inc

Kohei Yoshida kohei.yoshida at collabora.com
Fri Oct 18 23:10:10 PDT 2013


Rebased ref, commits from common ancestor:
commit 29654a9490a9783adc6554ab46a7c9c9903a6312
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sat Oct 19 02:07:21 2013 -0400

    Bail out early.
    
    Change-Id: Id2dcaebd8213704c777f77bf7fb735a9788d68bd

diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index d666218..e764d21 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -940,70 +940,75 @@ sc::RangeMatrix ScInterpreter::CompareMat( sc::CompareOptions* pOptions )
     }
 
     sc::RangeMatrix aRes;
-    if( !nGlobalError )
-    {
-        if (aMat[0].mpMat && aMat[1].mpMat)
-        {
-            SCSIZE nC0, nC1;
-            SCSIZE nR0, nR1;
-            aMat[0].mpMat->GetDimensions(nC0, nR0);
-            aMat[1].mpMat->GetDimensions(nC1, nR1);
-            SCSIZE nC = std::max( nC0, nC1 );
-            SCSIZE nR = std::max( nR0, nR1 );
-            aRes.mpMat = GetNewMat( nC, nR);
-            if (!aRes.mpMat)
-                return aRes;
-            for ( SCSIZE j=0; j<nC; j++ )
-            {
-                for ( SCSIZE k=0; k<nR; k++ )
-                {
-                    SCSIZE nCol = j, nRow = k;
-                    if (aMat[0].mpMat->ValidColRowOrReplicated(nCol, nRow) &&
-                        aMat[1].mpMat->ValidColRowOrReplicated(nCol, nRow))
+
+    if (nGlobalError)
+    {
+        nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
+        return aRes;
+    }
+
+    if (aMat[0].mpMat && aMat[1].mpMat)
+    {
+        SCSIZE nC0, nC1;
+        SCSIZE nR0, nR1;
+        aMat[0].mpMat->GetDimensions(nC0, nR0);
+        aMat[1].mpMat->GetDimensions(nC1, nR1);
+        SCSIZE nC = std::max( nC0, nC1 );
+        SCSIZE nR = std::max( nR0, nR1 );
+        aRes.mpMat = GetNewMat( nC, nR);
+        if (!aRes.mpMat)
+            return aRes;
+        for ( SCSIZE j=0; j<nC; j++ )
+        {
+            for ( SCSIZE k=0; k<nR; k++ )
+            {
+                SCSIZE nCol = j, nRow = k;
+                if (aMat[0].mpMat->ValidColRowOrReplicated(nCol, nRow) &&
+                    aMat[1].mpMat->ValidColRowOrReplicated(nCol, nRow))
+                {
+                    for ( short i=1; i>=0; i-- )
                     {
-                        for ( short i=1; i>=0; i-- )
+                        if (aMat[i].mpMat->IsString(j, k))
                         {
-                            if (aMat[i].mpMat->IsString(j, k))
-                            {
-                                aComp.bVal[i] = false;
-                                *aComp.pVal[i] = aMat[i].mpMat->GetString(j, k).getString();
-                                aComp.bEmpty[i] = aMat[i].mpMat->IsEmpty(j, k);
-                            }
-                            else
-                            {
-                                aComp.bVal[i] = true;
-                                aComp.nVal[i] = aMat[i].mpMat->GetDouble(j, k);
-                                aComp.bEmpty[i] = false;
-                            }
+                            aComp.bVal[i] = false;
+                            *aComp.pVal[i] = aMat[i].mpMat->GetString(j, k).getString();
+                            aComp.bEmpty[i] = aMat[i].mpMat->IsEmpty(j, k);
+                        }
+                        else
+                        {
+                            aComp.bVal[i] = true;
+                            aComp.nVal[i] = aMat[i].mpMat->GetDouble(j, k);
+                            aComp.bEmpty[i] = false;
                         }
-                        aRes.mpMat->PutDouble(sc::CompareFunc(aComp, pOptions), j, k);
                     }
-                    else
-                        aRes.mpMat->PutString(mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), j, k);
+                    aRes.mpMat->PutDouble(sc::CompareFunc(aComp, pOptions), j, k);
                 }
+                else
+                    aRes.mpMat->PutString(mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), j, k);
             }
         }
-        else if (aMat[0].mpMat || aMat[1].mpMat)
-        {
-            size_t i = ( aMat[0].mpMat ? 0 : 1);
-            SCSIZE nC, nR;
-            aMat[i].mpMat->GetDimensions(nC, nR);
-            aRes.mpMat = GetNewMat(nC, nR, false);
-            if (!aRes.mpMat)
-                return aRes;
+    }
+    else if (aMat[0].mpMat || aMat[1].mpMat)
+    {
+        size_t i = ( aMat[0].mpMat ? 0 : 1);
+        SCSIZE nC, nR;
+        aMat[i].mpMat->GetDimensions(nC, nR);
+        aRes.mpMat = GetNewMat(nC, nR, false);
+        if (!aRes.mpMat)
+            return aRes;
 
-            aRes.mnCol1 = aMat[i].mnCol1;
-            aRes.mnRow1 = aMat[i].mnRow1;
-            aRes.mnTab1 = aMat[i].mnTab1;
-            aRes.mnCol2 = aMat[i].mnCol2;
-            aRes.mnRow2 = aMat[i].mnRow2;
-            aRes.mnTab2 = aMat[i].mnTab2;
+        aRes.mnCol1 = aMat[i].mnCol1;
+        aRes.mnRow1 = aMat[i].mnRow1;
+        aRes.mnTab1 = aMat[i].mnTab1;
+        aRes.mnCol2 = aMat[i].mnCol2;
+        aRes.mnRow2 = aMat[i].mnRow2;
+        aRes.mnTab2 = aMat[i].mnTab2;
 
-            ScMatrix& rMat = *aMat[i].mpMat;
-            ScMatrix& rResMat = *aRes.mpMat;
-            rMat.CompareMatrix(rResMat, aComp, i, pOptions);
-        }
+        ScMatrix& rMat = *aMat[i].mpMat;
+        ScMatrix& rResMat = *aRes.mpMat;
+        rMat.CompareMatrix(rResMat, aComp, i, pOptions);
     }
+
     nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
     return aRes;
 }
commit 5df31d1ce047688fd759ffad6a881307197a7389
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Oct 18 23:31:23 2013 -0400

    Remove obsolete patches.
    
    Change-Id: Icf50e577b4ad472faa00a85e8ecc309bf2d953d0

diff --git a/mdds/0001-Combine-these-two-calls.-There-is-no-reason-why-they.patch b/mdds/0001-Combine-these-two-calls.-There-is-no-reason-why-they.patch
deleted file mode 100644
index 783210d..0000000
--- a/mdds/0001-Combine-these-two-calls.-There-is-no-reason-why-they.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From a2a1c432f65c0612bb6f1c23a50bd41d2cf0cbdd Mon Sep 17 00:00:00 2001
-From: Kohei Yoshida <kohei.yoshida at gmail.com>
-Date: Tue, 25 Jun 2013 08:08:09 -0400
-Subject: [PATCH] Combine these two calls. There is no reason why they have to
- separate.
-
----
- include/mdds/multi_type_vector_def.inl | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/include/mdds/multi_type_vector_def.inl b/include/mdds/multi_type_vector_def.inl
-index 36dde5e..685899b 100644
---- a/include/mdds/multi_type_vector_def.inl
-+++ b/c/d/include/mdds/multi_type_vector_def.inl
-@@ -1801,8 +1801,7 @@ void multi_type_vector<_CellBlockFunc>::swap_single_blocks(
-         else
-         {
-             // Insert a new block to store the new elements.
--            m_blocks.insert(m_blocks.begin()+block_index, NULL);
--            m_blocks[block_index] = new block(len);
-+            m_blocks.insert(m_blocks.begin()+block_index, new block(len));
-             block* blk = m_blocks[block_index];
-             blk->mp_data = dst_data.release();
-         }
--- 
-1.8.0
-
diff --git a/mdds/0001-Fix-it-here-too.patch b/mdds/0001-Fix-it-here-too.patch
deleted file mode 100644
index 5f99a3d..0000000
--- a/mdds/0001-Fix-it-here-too.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From e9fdebe0cad9277cfed994cae7fe9d08efbb4ba8 Mon Sep 17 00:00:00 2001
-From: Kohei Yoshida <kohei.yoshida at gmail.com>
-Date: Tue, 25 Jun 2013 09:42:19 -0400
-Subject: [PATCH] Fix it here too.
-
----
- include/mdds/multi_type_vector_def.inl | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/include/mdds/multi_type_vector_def.inl b/include/mdds/multi_type_vector_def.inl
-index 685899b..cea8ae0 100644
---- a/include/mdds/multi_type_vector_def.inl
-+++ b/c/d/include/mdds/multi_type_vector_def.inl
-@@ -1829,8 +1829,7 @@ void multi_type_vector<_CellBlockFunc>::swap_single_blocks(
-         }
-         else
-         {
--            m_blocks.insert(m_blocks.begin()+block_index+1, NULL);
--            m_blocks[block_index+1] = new block(len);
-+            m_blocks.insert(m_blocks.begin()+block_index+1, new block(len));
-             block* blk = m_blocks[block_index+1];
-             blk->mp_data = dst_data.release();
-         }
-@@ -2713,8 +2713,7 @@
-         else
-         {
-             // Insert a new block to store the new elements.
--            m_blocks.insert(m_blocks.begin()+dst_index+1, NULL);
--            m_blocks[dst_index+1] = new block(len);
-+            m_blocks.insert(m_blocks.begin()+dst_index+1, new block(len));
-             blk = m_blocks[dst_index+1];
-             blk->mp_data = element_block_func::create_new_block(cat_src, 0);
-             assert(blk->mp_data);
--- 
-1.8.0
-
diff --git a/mdds/UnpackedTarball_mdds.mk b/mdds/UnpackedTarball_mdds.mk
index 9d85d74..69fbf18 100644
--- a/mdds/UnpackedTarball_mdds.mk
+++ b/mdds/UnpackedTarball_mdds.mk
@@ -16,8 +16,6 @@ $(eval $(call gb_UnpackedTarball_set_patchlevel,mdds,3))
 $(eval $(call gb_UnpackedTarball_add_patches,mdds,\
 	mdds/mdds_0.6.0.patch \
 	mdds/0001-Workaround-for-an-old-gcc-bug.patch \
-	mdds/0001-Combine-these-two-calls.-There-is-no-reason-why-they.patch \
-	mdds/0001-Fix-it-here-too.patch \
 ))
 
 # vim: set noet sw=4 ts=4:
commit 45759608eaa3112819e7580c20d18786cbf9740b
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Oct 18 23:27:54 2013 -0400

    Update mdds to 0.9.1.
    
    Change-Id: I514e405f3a9768dcaab00a88c90d72bc54d12713

diff --git a/download.lst b/download.lst
index 120ac9b..d4d0057 100644
--- a/download.lst
+++ b/download.lst
@@ -69,7 +69,7 @@ export LIBXML_TARBALL := 7740a8ec23878a2f50120e1faa2730f2-libxml2-2.7.6.tar.gz
 export LIBXSLT_TARBALL := e61d0364a30146aaa3001296f853b2b9-libxslt-1.1.26.tar.gz
 export LPSOLVE_TARBALL := 26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz
 export MARIADB_TARBALL := 05f84c95b610c21c5fd510d10debcabf-mariadb-native-client-1.0.0.tar.bz2
-export MDDS_TARBALL := 782735c43c742a27ebe19fb1871fed8f-mdds_0.9.0.tar.bz2
+export MDDS_TARBALL := 450728fc82e0aa2b588c1e79d5694595-mdds_0.9.1.tar.bz2
 export MYSQLCPPCONN_TARBALL := 0981bda6548a8c8233ffce2b6e4b2a23-mysql-connector-c++-1.1.0.tar.gz
 export MYTHES_TARBALL := 46e92b68e31e858512b680b3b61dc4c1-mythes-1.2.3.tar.gz
 export NEON_TARBALL := ff369e69ef0f0143beb5626164e87ae2-neon-0.29.5.tar.gz
commit a130c38bbcc9a0a5bb32e084ffbda34e561b2373
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Oct 18 19:49:14 2013 -0400

    Try constructing & initializing the matrix in one step.
    
    This uses multi_type_matrix's new constructor that allows array data
    assignment.
    
    Change-Id: Ief01aefc1cc770aca702de7117c7e72c51fd4c33

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index f711e05..cf399c9 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -122,11 +122,11 @@ class CompareMatrixElemFunc : std::unary_function<MatrixImplType::element_block_
 {
     static _Comp maComp;
 
-    MatrixImplType maNewMat;
     std::vector<bool> maNewMatValues;
+    size_t mnRow;
+    size_t mnCol;
 public:
-    CompareMatrixElemFunc( size_t nRow, size_t nCol ) :
-        maNewMat(nRow, nCol, false)
+    CompareMatrixElemFunc( size_t nRow, size_t nCol ) : mnRow(nRow), mnCol(nCol)
     {
         maNewMatValues.reserve(nRow*nCol);
     }
@@ -178,8 +178,8 @@ public:
 
     void swap( MatrixImplType& rMat )
     {
-        maNewMat.set(0, 0, maNewMatValues.begin(), maNewMatValues.end());
-        rMat.swap(maNewMat);
+        MatrixImplType aNewMat(mnRow, mnCol, maNewMatValues.begin(), maNewMatValues.end());
+        rMat.swap(aNewMat);
     }
 };
 
commit 790aec7e840b2fdbb6870d7973aeb581507442f8
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Oct 18 14:52:08 2013 -0400

    Remove all uses of Pos and ConstPos. They are slow.
    
    Change-Id: I27f68e67eebfd1ce4be29b24147e5586c8f9f85e

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 7d6d911..6fe7a5e 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -144,31 +144,6 @@ public:
             mfFirst(r.mfFirst), mfRest(r.mfRest), mnCount(r.mnCount) {}
     };
 
-    struct Pos;
-    struct ConstPos;
-
-    static void DeletePosition( const Pos* p );
-    static void DeletePosition( const ConstPos* p );
-
-    struct PosDeleter : std::unary_function<const Pos*, void>
-    {
-        void operator() (const Pos* p)
-        {
-            DeletePosition(p);
-        }
-    };
-
-    struct ConstPosDeleter : std::unary_function<const ConstPos*, void>
-    {
-        void operator() (const ConstPos* p)
-        {
-            DeletePosition(p);
-        }
-    };
-
-    typedef boost::interprocess::unique_ptr<Pos, PosDeleter> PosRef;
-    typedef boost::interprocess::unique_ptr<ConstPos, ConstPosDeleter> ConstPosRef;
-
     /// The maximum number of elements a matrix may have at runtime.
     inline static size_t GetElementsMax()
     {
@@ -321,8 +296,6 @@ public:
     /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate
     /// an empty string!
     ScMatrixValue Get( SCSIZE nC, SCSIZE nR) const;
-    ScMatrixValue Get( const Pos& rPos ) const;
-    ScMatrixValue Get( const ConstPos& rPos ) const;
 
     /// @return <TRUE/> if string or empty or empty path, in fact non-value.
     sal_Bool IsString( SCSIZE nIndex ) const;
@@ -351,31 +324,6 @@ public:
     /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties
     sal_Bool IsNumeric() const;
 
-    Pos* GetPosition( size_t nC, size_t nR );
-    ConstPos* GetConstPosition( size_t nC, size_t nR ) const;
-
-    bool NextPosition( Pos& rPos );
-    bool NextPosition( ConstPos& rPos ) const;
-
-    bool IsValue( const Pos& rPos ) const;
-    bool IsValue( const ConstPos& rPos ) const;
-
-    bool IsEmpty( const Pos& rPos ) const;
-    bool IsEmpty( const ConstPos& rPos ) const;
-
-    double GetDouble( const Pos& rPos ) const;
-    double GetDouble( const ConstPos& rPos ) const;
-
-    svl::SharedString GetString( const Pos& rPos ) const;
-    svl::SharedString GetString( const ConstPos& rPos ) const;
-
-    void PutDouble( double fVal, Pos& rPos );
-    void PutString( const svl::SharedString& rStr, Pos& rPos );
-    void PutEmpty( Pos& rPos );
-    void PutEmptyPath( Pos& rPos );
-    void PutError( sal_uInt16 nErr, Pos& rPos );
-    void PutBoolean( bool bVal, Pos& rPos );
-
     void MatTrans( ScMatrix& mRes) const;
     void MatCopy ( ScMatrix& mRes) const;
 
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index b15866f..f711e05 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -67,24 +67,6 @@ struct custom_string_trait
 
 typedef mdds::multi_type_matrix<custom_string_trait> MatrixImplType;
 
-struct ScMatrix::Pos
-{
-    MatrixImplType::position_type maPos;
-    MatrixImplType::position_type maPosFlag;
-};
-
-struct ScMatrix::ConstPos
-{
-    MatrixImplType::const_position_type maPos;
-    MatrixImplType::const_position_type maPosFlag;
-
-    ConstPos() {}
-    ConstPos( const ScMatrix::ConstPos& r ) :
-        maPos(r.maPos), maPosFlag(r.maPosFlag) {}
-    ConstPos( const ScMatrix::Pos& r ) :
-        maPos(r.maPos), maPosFlag(r.maPosFlag) {}
-};
-
 namespace {
 
 struct ElemEqualZero : public unary_function<double, bool>
@@ -251,7 +233,6 @@ public:
     svl::SharedString GetString( SCSIZE nIndex) const;
     svl::SharedString GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const;
     ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const;
-    ScMatrixValue Get( const ScMatrix::ConstPos& rPos ) const;
     bool IsString( SCSIZE nIndex ) const;
     bool IsString( SCSIZE nC, SCSIZE nR ) const;
     bool IsEmpty( SCSIZE nC, SCSIZE nR ) const;
@@ -262,24 +243,6 @@ public:
     bool IsBoolean( SCSIZE nC, SCSIZE nR ) const;
     bool IsNumeric() const;
 
-    ScMatrix::Pos* GetPosition( size_t nC, size_t nR );
-    ScMatrix::ConstPos* GetConstPosition( size_t nC, size_t nR ) const;
-
-    bool NextPosition( ScMatrix::Pos& rPos );
-    bool NextPosition( ScMatrix::ConstPos& rPos ) const;
-
-    bool IsValue( const ScMatrix::ConstPos& rPos ) const;
-    bool IsEmpty( const ScMatrix::ConstPos& rPos ) const;
-    double GetDouble( const ScMatrix::ConstPos& rPos ) const;
-    svl::SharedString GetString( const ScMatrix::ConstPos& rPos ) const;
-
-    void PutDouble( double fVal, ScMatrix::Pos& rPos );
-    void PutString( const svl::SharedString& rStr, ScMatrix::Pos& rPos );
-    void PutEmpty( ScMatrix::Pos& rPos );
-    void PutEmptyPath( ScMatrix::Pos& rPos );
-    void PutError( sal_uInt16 nErr, ScMatrix::Pos& rPos );
-    void PutBoolean( bool bVal, ScMatrix::Pos& rPos );
-
     void MatCopy(ScMatrixImpl& mRes) const;
     void MatTrans(ScMatrixImpl& mRes) const;
     void FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 );
@@ -672,34 +635,6 @@ ScMatrixValue ScMatrixImpl::Get(SCSIZE nC, SCSIZE nR) const
     return aVal;
 }
 
-ScMatrixValue ScMatrixImpl::Get( const ScMatrix::ConstPos& rPos ) const
-{
-    ScMatrixValue aVal;
-    mdds::mtm::element_t eType = maMat.get_type(rPos.maPos);
-    switch (eType)
-    {
-        case mdds::mtm::element_boolean:
-            aVal.nType = SC_MATVAL_BOOLEAN;
-            aVal.fVal = maMat.get_boolean(rPos.maPos);
-        break;
-        case mdds::mtm::element_numeric:
-            aVal.nType = SC_MATVAL_VALUE;
-            aVal.fVal = MatrixImplType::numeric_block_type::at(*rPos.maPos.first->data, rPos.maPos.second);
-        break;
-        case mdds::mtm::element_string:
-            aVal.nType = SC_MATVAL_STRING;
-            aVal.aStr = MatrixImplType::string_block_type::at(*rPos.maPos.first->data, rPos.maPos.second);
-        break;
-        case mdds::mtm::element_empty:
-            // Empty path equals empty plus flag.
-            aVal.nType = maMatFlag.get_boolean(rPos.maPosFlag) ? SC_MATVAL_EMPTYPATH : SC_MATVAL_EMPTY;
-            aVal.fVal = 0.0;
-        default:
-            ;
-    }
-    return aVal;
-}
-
 bool ScMatrixImpl::IsString( SCSIZE nIndex ) const
 {
     SCSIZE nC, nR;
@@ -785,123 +720,6 @@ bool ScMatrixImpl::IsNumeric() const
     return maMat.numeric();
 }
 
-ScMatrix::Pos* ScMatrixImpl::GetPosition( size_t nC, size_t nR )
-{
-    ScMatrix::Pos* pRet = new ScMatrix::Pos;
-    pRet->maPos = maMat.position(nR, nC);
-    pRet->maPosFlag = maMatFlag.position(nR, nC);
-    return pRet;
-}
-
-ScMatrix::ConstPos* ScMatrixImpl::GetConstPosition( size_t nC, size_t nR ) const
-{
-    ScMatrix::ConstPos* pRet = new ScMatrix::ConstPos;
-    pRet->maPos = maMat.position(nR, nC);
-    pRet->maPosFlag = maMatFlag.position(nR, nC);
-    return pRet;
-}
-
-bool ScMatrixImpl::NextPosition( ScMatrix::Pos& rPos )
-{
-    rPos.maPos = MatrixImplType::next_position(rPos.maPos);
-    rPos.maPosFlag = MatrixImplType::next_position(rPos.maPosFlag);
-    return rPos.maPos != maMat.end_position();
-}
-
-bool ScMatrixImpl::NextPosition( ScMatrix::ConstPos& rPos ) const
-{
-    rPos.maPos = MatrixImplType::next_position(rPos.maPos);
-    rPos.maPosFlag = MatrixImplType::next_position(rPos.maPosFlag);
-    return rPos.maPos != maMat.end_position();
-}
-
-bool ScMatrixImpl::IsValue( const ScMatrix::ConstPos& rPos ) const
-{
-    switch (maMat.get_type(rPos.maPos))
-    {
-        case mdds::mtm::element_boolean:
-        case mdds::mtm::element_numeric:
-            return true;
-        default:
-            ;
-    }
-    return false;
-}
-
-bool ScMatrixImpl::IsEmpty( const ScMatrix::ConstPos& rPos ) const
-{
-    return maMat.get_type(rPos.maPos) == mdds::mtm::element_empty && !maMatFlag.get_boolean(rPos.maPosFlag);
-}
-
-double ScMatrixImpl::GetDouble( const ScMatrix::ConstPos& rPos ) const
-{
-    double fVal = maMat.get_numeric(rPos.maPos);
-    if (pErrorInterpreter)
-    {
-        sal_uInt16 nError = GetDoubleErrorValue(fVal);
-        if (nError)
-            SetErrorAtInterpreter( nError);
-    }
-    return fVal;
-}
-
-
-svl::SharedString ScMatrixImpl::GetString( const ScMatrix::ConstPos& rPos ) const
-{
-    double fErr = 0.0;
-    switch (maMat.get_type(rPos.maPos))
-    {
-        case mdds::mtm::element_string:
-            return maMat.get_string(rPos.maPos);
-        case mdds::mtm::element_empty:
-            return svl::SharedString::getEmptyString();
-        case mdds::mtm::element_numeric:
-        case mdds::mtm::element_boolean:
-            OSL_FAIL("ScMatrixImpl::GetString: access error, no string");
-            fErr = maMat.get_numeric(rPos.maPos);
-        default:
-            OSL_FAIL("ScMatrixImpl::GetString: access error, no string");
-    }
-
-    SetErrorAtInterpreter(GetDoubleErrorValue(fErr));
-    return svl::SharedString::getEmptyString();
-}
-
-void ScMatrixImpl::PutDouble( double fVal, ScMatrix::Pos& rPos )
-{
-    if (maMat.get_type(rPos.maPos) == mdds::mtm::element_numeric)
-        MatrixImplType::numeric_block_type::at(*rPos.maPos.first->data, rPos.maPos.second) = fVal;
-    else
-        rPos.maPos = maMat.set(rPos.maPos, fVal);
-}
-
-void ScMatrixImpl::PutString( const svl::SharedString& rStr, ScMatrix::Pos& rPos )
-{
-    rPos.maPos = maMat.set(rPos.maPos, rStr);
-}
-
-void ScMatrixImpl::PutEmpty( ScMatrix::Pos& rPos )
-{
-    rPos.maPos = maMat.set_empty(rPos.maPos);
-    rPos.maPosFlag = maMatFlag.set(rPos.maPosFlag, false); // zero flag to indicate that this is 'empty', not 'empty path'.
-}
-
-void ScMatrixImpl::PutEmptyPath( ScMatrix::Pos& rPos )
-{
-    rPos.maPos = maMat.set_empty(rPos.maPos);
-    rPos.maPosFlag = maMatFlag.set(rPos.maPosFlag, true); // non-zero flag to indicate empty 'path'.
-}
-
-void ScMatrixImpl::PutError( sal_uInt16 nErr, ScMatrix::Pos& rPos )
-{
-    rPos.maPos = maMat.set(rPos.maPos, CreateDoubleError(nErr));
-}
-
-void ScMatrixImpl::PutBoolean( bool bVal, ScMatrix::Pos& rPos )
-{
-    rPos.maPos = maMat.set(rPos.maPos, bVal);
-}
-
 void ScMatrixImpl::MatCopy(ScMatrixImpl& mRes) const
 {
     if (maMat.size().row > mRes.maMat.size().row || maMat.size().column > mRes.maMat.size().column)
@@ -1995,16 +1813,6 @@ ScMatrixValue ScMatrix::Get(SCSIZE nC, SCSIZE nR) const
     return pImpl->Get(nC, nR);
 }
 
-ScMatrixValue ScMatrix::Get( const Pos& rPos ) const
-{
-    return pImpl->Get(rPos);
-}
-
-ScMatrixValue ScMatrix::Get( const ConstPos& rPos ) const
-{
-    return pImpl->Get(rPos);
-}
-
 sal_Bool ScMatrix::IsString( SCSIZE nIndex ) const
 {
     return pImpl->IsString(nIndex);
@@ -2050,106 +1858,6 @@ sal_Bool ScMatrix::IsNumeric() const
     return pImpl->IsNumeric();
 }
 
-ScMatrix::Pos* ScMatrix::GetPosition( size_t nC, size_t nR )
-{
-    return pImpl->GetPosition(nC, nR);
-}
-
-ScMatrix::ConstPos* ScMatrix::GetConstPosition( size_t nC, size_t nR ) const
-{
-    return pImpl->GetConstPosition(nC, nR);
-}
-
-void ScMatrix::DeletePosition( const Pos* p )
-{
-    delete p;
-}
-
-void ScMatrix::DeletePosition( const ConstPos* p )
-{
-    delete p;
-}
-
-bool ScMatrix::NextPosition( Pos& rPos )
-{
-    return pImpl->NextPosition(rPos);
-}
-
-bool ScMatrix::NextPosition( ConstPos& rPos ) const
-{
-    return pImpl->NextPosition(rPos);
-}
-
-bool ScMatrix::IsValue( const Pos& rPos ) const
-{
-    return pImpl->IsValue(rPos);
-}
-
-bool ScMatrix::IsValue( const ConstPos& rPos ) const
-{
-    return pImpl->IsValue(rPos);
-}
-
-bool ScMatrix::IsEmpty( const Pos& rPos ) const
-{
-    return pImpl->IsEmpty(rPos);
-}
-
-bool ScMatrix::IsEmpty( const ConstPos& rPos ) const
-{
-    return pImpl->IsEmpty(rPos);
-}
-
-double ScMatrix::GetDouble( const Pos& rPos ) const
-{
-    return pImpl->GetDouble(rPos);
-}
-
-double ScMatrix::GetDouble( const ConstPos& rPos ) const
-{
-    return pImpl->GetDouble(rPos);
-}
-
-svl::SharedString ScMatrix::GetString( const Pos& rPos ) const
-{
-    return pImpl->GetString(rPos);
-}
-
-svl::SharedString ScMatrix::GetString( const ConstPos& rPos ) const
-{
-    return pImpl->GetString(rPos);
-}
-
-void ScMatrix::PutDouble( double fVal, Pos& rPos )
-{
-    pImpl->PutDouble(fVal, rPos);
-}
-
-void ScMatrix::PutString( const svl::SharedString& rStr, Pos& rPos )
-{
-    pImpl->PutString(rStr, rPos);
-}
-
-void ScMatrix::PutEmpty( Pos& rPos )
-{
-    pImpl->PutEmpty(rPos);
-}
-
-void ScMatrix::PutEmptyPath( Pos& rPos )
-{
-    pImpl->PutEmptyPath(rPos);
-}
-
-void ScMatrix::PutError( sal_uInt16 nErr, Pos& rPos )
-{
-    pImpl->PutError(nErr, rPos);
-}
-
-void ScMatrix::PutBoolean( bool bVal, Pos& rPos )
-{
-    pImpl->PutBoolean(bVal, rPos);
-}
-
 void ScMatrix::MatCopy(ScMatrix& mRes) const
 {
     pImpl->MatCopy(*mRes.pImpl);
commit 0b08d0627da68311140ea0d18983e2f1aee92f5b
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Oct 18 12:37:24 2013 -0400

    vector with reserve() is slightly faster than deque here.
    
    Change-Id: I9c2203662daa586e3fdbc9650b6ff61365c5bc60

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index a5487a7..b15866f 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -141,10 +141,13 @@ class CompareMatrixElemFunc : std::unary_function<MatrixImplType::element_block_
     static _Comp maComp;
 
     MatrixImplType maNewMat;
-    std::deque<bool> maNewMatValues;
+    std::vector<bool> maNewMatValues;
 public:
     CompareMatrixElemFunc( size_t nRow, size_t nCol ) :
-        maNewMat(nRow, nCol, false) {}
+        maNewMat(nRow, nCol, false)
+    {
+        maNewMatValues.reserve(nRow*nCol);
+    }
 
     void operator() (const MatrixImplType::element_block_node_type& node)
     {
commit 7460ddb0f2834f1a1e9ccd6967276d4ec0f612ac
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Oct 18 11:07:38 2013 -0400

    Slightly optimize matrix value traversal.
    
    Change-Id: Idbcb2348ff7f4a5df32d66761849e3a92b4eb794

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 5e9800e..7d6d911 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -404,7 +404,15 @@ public:
     void CompareMatrix(
         ScMatrix& rResMat, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions = NULL ) const;
 
-    void GetDoubleArray( std::vector<double>& rArray ) const;
+    /**
+     * Convert the content of matrix into a linear array of numeric values.
+     * String elements are mapped to NaN's and empty elements are mapped to
+     * either NaN or zero values.
+     *
+     * @param bEmptyAsZero if true empty elements are mapped to zero values,
+     *                     otherwise they become NaN values.
+     */
+    void GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero = true ) const;
     void MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const;
 
     ScMatrix& operator+= ( const ScMatrix& r );
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 9032a5e..d666218 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5360,7 +5360,7 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
             }
 
             if (nGlobalError)
-                continue;   // and bail out, no need to evaluate other arguments
+                return 0;   // and bail out, no need to evaluate other arguments
 
             // take range
             nParam = 1;
@@ -5398,6 +5398,7 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
                         if (!pQueryMatrix)
                         {
                             SetError( errIllegalParameter);
+                            return 0;
                         }
                         nCol1 = 0;
                         nRow1 = 0;
@@ -5411,9 +5412,13 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
                     break;
                 default:
                     SetError( errIllegalParameter);
+                    return 0;
             }
             if ( nTab1 != nTab2 )
+            {
                 SetError( errIllegalArgument);
+                return 0;
+            }
 
             // All reference ranges must be of same dimension and size.
             if (!nDimensionCols)
@@ -5421,80 +5426,87 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
             if (!nDimensionRows)
                 nDimensionRows = nRow2 - nRow1 + 1;
             if ((nDimensionCols != (nCol2 - nCol1 + 1)) || (nDimensionRows != (nRow2 - nRow1 + 1)))
+            {
                 SetError ( errIllegalArgument);
+                return 0;
+            }
 
             // recalculate matrix values
-            if (nGlobalError == 0)
+            if (nGlobalError)
+                return 0;
+
+            // initialize temporary result matrix
+            if (!pResMat)
             {
-                // initialize temporary result matrix
+                SCSIZE nResC, nResR;
+                nResC = nCol2 - nCol1 + 1;
+                nResR = nRow2 - nRow1 + 1;
+                pResMat = GetNewMat(nResC, nResR, false);
                 if (!pResMat)
                 {
-                    SCSIZE nResC, nResR;
-                    nResC = nCol2 - nCol1 + 1;
-                    nResR = nRow2 - nRow1 + 1;
-                    pResMat = GetNewMat(nResC, nResR, false);
-                    if (!pResMat)
-                        SetError( errIllegalParameter);
+                    SetError( errIllegalParameter);
+                    return 0;
                 }
+            }
 
-                ScQueryParam rParam;
-                rParam.nRow1       = nRow1;
-                rParam.nRow2       = nRow2;
+            ScQueryParam rParam;
+            rParam.nRow1       = nRow1;
+            rParam.nRow2       = nRow2;
 
-                ScQueryEntry& rEntry = rParam.GetEntry(0);
-                ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
-                rEntry.bDoQuery = true;
-                if (!bIsString)
-                {
-                    rItem.meType = ScQueryEntry::ByValue;
-                    rItem.mfVal = fVal;
-                    rEntry.eOp = SC_EQUAL;
-                }
-                else
+            ScQueryEntry& rEntry = rParam.GetEntry(0);
+            ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+            rEntry.bDoQuery = true;
+            if (!bIsString)
+            {
+                rItem.meType = ScQueryEntry::ByValue;
+                rItem.mfVal = fVal;
+                rEntry.eOp = SC_EQUAL;
+            }
+            else
+            {
+                rParam.FillInExcelSyntax(pDok->GetSharedStringPool(), aString.getString(), 0);
+                sal_uInt32 nIndex = 0;
+                bool bNumber = pFormatter->IsNumberFormat(
+                        rItem.maString.getString(), nIndex, rItem.mfVal);
+                rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
+                if (rItem.meType == ScQueryEntry::ByString)
+                    rParam.bRegExp = MayBeRegExp(rItem.maString.getString(), pDok);
+            }
+            ScAddress aAdr;
+            aAdr.SetTab( nTab1 );
+            rParam.nCol1  = nCol1;
+            rParam.nCol2  = nCol2;
+            rEntry.nField = nCol1;
+            SCsCOL nColDiff = -nCol1;
+            SCsROW nRowDiff = -nRow1;
+            if (pQueryMatrix)
+            {
+                // Never case-sensitive.
+                sc::CompareOptions aOptions( pDok, rEntry, rParam.bRegExp);
+                ScMatrixRef pResultMatrix = QueryMat( pQueryMatrix, aOptions);
+                if (nGlobalError || !pResultMatrix)
                 {
-                    rParam.FillInExcelSyntax(pDok->GetSharedStringPool(), aString.getString(), 0);
-                    sal_uInt32 nIndex = 0;
-                    bool bNumber = pFormatter->IsNumberFormat(
-                            rItem.maString.getString(), nIndex, rItem.mfVal);
-                    rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
-                    if (rItem.meType == ScQueryEntry::ByString)
-                        rParam.bRegExp = MayBeRegExp(rItem.maString.getString(), pDok);
+                    SetError( errIllegalParameter);
+                    return 0;
                 }
-                ScAddress aAdr;
-                aAdr.SetTab( nTab1 );
-                rParam.nCol1  = nCol1;
-                rParam.nCol2  = nCol2;
-                rEntry.nField = nCol1;
-                SCsCOL nColDiff = -nCol1;
-                SCsROW nRowDiff = -nRow1;
-                if (pQueryMatrix)
-                {
-                    // Never case-sensitive.
-                    sc::CompareOptions aOptions( pDok, rEntry, rParam.bRegExp);
-                    ScMatrixRef pResultMatrix = QueryMat( pQueryMatrix, aOptions);
-                    if (nGlobalError || !pResultMatrix)
-                    {
-                        SetError( errIllegalParameter);
-                    }
 
-                    // query and result matrices have same geometry, and the
-                    // result matrix is filled with boolean values.
-                    *pResMat += *pResultMatrix;
-                }
-                else
+                // query and result matrices have same geometry, and the
+                // result matrix is filled with boolean values.
+                *pResMat += *pResultMatrix;
+            }
+            else
+            {
+                ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
+                // Increment Entry.nField in iterator when switching to next column.
+                aCellIter.SetAdvanceQueryParamEntryField( true );
+                if ( aCellIter.GetFirst() )
                 {
-                    ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
-                    // Increment Entry.nField in iterator when switching to next column.
-                    aCellIter.SetAdvanceQueryParamEntryField( true );
-                    if ( aCellIter.GetFirst() )
+                    do
                     {
-                        do
-                        {
-                            SCSIZE nC = aCellIter.GetCol() + nColDiff;
-                            SCSIZE nR = aCellIter.GetRow() + nRowDiff;
-                            pResMat->PutDouble(pResMat->GetDouble(nC, nR)+1.0, nC, nR);
-                        } while ( aCellIter.GetNext() );
-                    }
+                        SCSIZE nC = aCellIter.GetCol() + nColDiff;
+                        SCSIZE nR = aCellIter.GetRow() + nRowDiff;
+                        pResMat->PutDouble(pResMat->GetDouble(nC, nR)+1.0, nC, nR);
+                    } while ( aCellIter.GetNext() );
                 }
             }
             nParamCount -= 2;
@@ -5555,13 +5567,20 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
                     break;
                 default:
                     SetError( errIllegalParameter);
+                    return 0;
             }
             if ( nMainTab1 != nMainTab2 )
+            {
                 SetError( errIllegalArgument);
+                return 0;
+            }
 
             // All reference ranges must be of same dimension and size.
             if ((nDimensionCols != (nMainCol2 - nMainCol1 + 1)) || (nDimensionRows != (nMainRow2 - nMainRow1 + 1)))
+            {
                 SetError ( errIllegalArgument);
+                return 0;
+            }
 
             if (nGlobalError)
                 return 0;   // bail out
@@ -5571,28 +5590,34 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
             aAdr.SetTab( nMainTab1 );
             if (pMainMatrix)
             {
-                SCSIZE nC, nR;
-                pResMat->GetDimensions(nC, nR);
-                for (SCSIZE nCol = 0; nCol < nC; ++nCol)
+                std::vector<double> aResValues, aMainValues;
+                pResMat->GetDoubleArray(aResValues, true);
+                pMainMatrix->GetDoubleArray(aMainValues, false); // Map empty values to NaN's.
+                if (aResValues.size() != aMainValues.size())
                 {
-                    for (SCSIZE nRow = 0; nRow < nR; ++nRow)
+                    SetError( errIllegalArgument);
+                    return 0;
+                }
+
+                std::vector<double>::const_iterator itRes = aResValues.begin(), itResEnd = aResValues.end();
+                std::vector<double>::const_iterator itMain = aMainValues.begin();
+                for (; itRes != itResEnd; ++itRes, ++itMain)
+                {
+                    if (*itRes != nQueryCount)
+                        continue;
+
+                    fVal = *itMain;
+                    if (rtl::math::isNan(fVal))
+                        continue;
+
+                    ++fCount;
+                    if (bNull && fVal != 0.0)
                     {
-                        if (pResMat->GetDouble( nCol, nRow) == nQueryCount)
-                        {
-                            if (pMainMatrix->IsValue( nCol, nRow))
-                            {
-                                fVal = pMainMatrix->GetDouble( nCol, nRow);
-                                ++fCount;
-                                if ( bNull && fVal != 0.0 )
-                                {
-                                    bNull = false;
-                                    fMem = fVal;
-                                }
-                                else
-                                    fSum += fVal;
-                            }
-                        }
+                        bNull = false;
+                        fMem = fVal;
                     }
+                    else
+                        fSum += fVal;
                 }
             }
             else
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 29dcda7..a5487a7 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -302,7 +302,7 @@ public:
 
     void CompareMatrix( ScMatrix& rResMat, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) const;
 
-    void GetDoubleArray( std::vector<double>& rArray ) const;
+    void GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero ) const;
     void MergeDoubleArray( std::vector<double>& rArray, ScMatrix::Op eOp ) const;
     void AddValues( const ScMatrixImpl& rMat );
 
@@ -1482,8 +1482,11 @@ class ToDoubleArray : std::unary_function<MatrixImplType::element_block_type, vo
     std::vector<double> maArray;
     std::vector<double>::iterator miPos;
     double mfNaN;
+    bool mbEmptyAsZero;
+
 public:
-    ToDoubleArray(size_t nSize) : maArray(nSize, 0.0), miPos(maArray.begin())
+    ToDoubleArray( size_t nSize, bool bEmptyAsZero ) :
+        maArray(nSize, 0.0), miPos(maArray.begin()), mbEmptyAsZero(bEmptyAsZero)
     {
         rtl::math::setNan(&mfNaN);
     }
@@ -1517,7 +1520,17 @@ public:
             }
             break;
             case mdds::mtm::element_empty:
-                std::advance(miPos, node.size);
+            {
+                if (mbEmptyAsZero)
+                {
+                    std::advance(miPos, node.size);
+                    return;
+                }
+
+                for (size_t i = 0; i < node.size; ++i, ++miPos)
+                    *miPos = mfNaN;
+            }
+            break;
             default:
                 ;
         }
@@ -1669,10 +1682,10 @@ void ScMatrixImpl::CompareMatrix(
         rResMat.PutDouble(&rResVal[0], rResVal.size(), 0, 0);
 }
 
-void ScMatrixImpl::GetDoubleArray( std::vector<double>& rArray ) const
+void ScMatrixImpl::GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero ) const
 {
     MatrixImplType::size_pair_type aSize = maMat.size();
-    ToDoubleArray aFunc(aSize.row*aSize.column);
+    ToDoubleArray aFunc(aSize.row*aSize.column, bEmptyAsZero);
     maMat.walk(aFunc);
     aFunc.swap(rArray);
 }
@@ -2239,9 +2252,9 @@ void ScMatrix::CompareMatrix( ScMatrix& rResMat, sc::Compare& rComp, size_t nMat
     pImpl->CompareMatrix(rResMat, rComp, nMatPos, pOptions);
 }
 
-void ScMatrix::GetDoubleArray( std::vector<double>& rArray ) const
+void ScMatrix::GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero ) const
 {
-    pImpl->GetDoubleArray(rArray);
+    pImpl->GetDoubleArray(rArray, bEmptyAsZero);
 }
 
 void ScMatrix::MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const
commit 1a590708f5ed69d2387e13334f347160e23c63f6
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Oct 18 00:22:11 2013 -0400

    Faster way to add two result matrices.
    
    Change-Id: I347aec7de10a943d7f91c468cd6e393f980e53b6

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 8317b85..5e9800e 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -167,7 +167,7 @@ public:
     };
 
     typedef boost::interprocess::unique_ptr<Pos, PosDeleter> PosRef;
-    typedef boost::interprocess::unique_ptr<ConstPos, PosDeleter> ConstPosRef;
+    typedef boost::interprocess::unique_ptr<ConstPos, ConstPosDeleter> ConstPosRef;
 
     /// The maximum number of elements a matrix may have at runtime.
     inline static size_t GetElementsMax()
@@ -407,6 +407,8 @@ public:
     void GetDoubleArray( std::vector<double>& rArray ) const;
     void MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const;
 
+    ScMatrix& operator+= ( const ScMatrix& r );
+
 #if DEBUG_MATRIX
     void Dump() const;
 #endif
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 5961bc5..9032a5e 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5477,19 +5477,9 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
                         SetError( errIllegalParameter);
                     }
 
-                    for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
-                    {
-                        for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
-                        {
-                            if (pResultMatrix->IsValue( nCol, nRow) &&
-                                    pResultMatrix->GetDouble( nCol, nRow))
-                            {
-                                SCSIZE nC = nCol + nColDiff;
-                                SCSIZE nR = nRow + nRowDiff;
-                                pResMat->PutDouble(pResMat->GetDouble(nC, nR)+1.0, nC, nR);
-                            }
-                        }
-                    }
+                    // query and result matrices have same geometry, and the
+                    // result matrix is filled with boolean values.
+                    *pResMat += *pResultMatrix;
                 }
                 else
                 {
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 5d8cc9a2..29dcda7 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -304,6 +304,7 @@ public:
 
     void GetDoubleArray( std::vector<double>& rArray ) const;
     void MergeDoubleArray( std::vector<double>& rArray, ScMatrix::Op eOp ) const;
+    void AddValues( const ScMatrixImpl& rMat );
 
 #if DEBUG_MATRIX
     void Dump() const;
@@ -1696,6 +1697,61 @@ void ScMatrixImpl::MergeDoubleArray( std::vector<double>& rArray, ScMatrix::Op e
     }
 }
 
+void ScMatrixImpl::AddValues( const ScMatrixImpl& rMat )
+{
+    const MatrixImplType& rOther = rMat.maMat;
+    MatrixImplType::size_pair_type aSize = maMat.size();
+    if (aSize != rOther.size())
+        // Geometry must match.
+        return;
+
+    // For now, we only add two matricies if and only if 1) the receiving
+    // matrix consists only of one numeric block, and 2) the other matrix
+    // consists of either one numeric block or one boolean block.  In the
+    // future, we may want to be more flexible support matricies that consist
+    // of multiple blocks.
+
+    MatrixImplType::position_type aPos1 = maMat.position(0, 0);
+    MatrixImplType::const_position_type aPos2 = rOther.position(0, 0);
+    if (MatrixImplType::to_mtm_type(aPos1.first->type) != mdds::mtm::element_numeric)
+        return;
+
+    if (aPos1.first->size != aPos2.first->size)
+        return;
+
+    if (aPos1.first->size != aSize.row * aSize.column)
+        return;
+
+    MatrixImplType::numeric_block_type::iterator it =
+        MatrixImplType::numeric_block_type::begin(*aPos1.first->data);
+    MatrixImplType::numeric_block_type::iterator itEnd =
+        MatrixImplType::numeric_block_type::end(*aPos1.first->data);
+
+    switch (MatrixImplType::to_mtm_type(aPos2.first->type))
+    {
+        case mdds::mtm::element_boolean:
+        {
+            MatrixImplType::boolean_block_type::iterator it2 =
+                MatrixImplType::boolean_block_type::begin(*aPos2.first->data);
+
+            for (; it != itEnd; ++it, ++it2)
+                *it += *it2;
+        }
+        break;
+        case mdds::mtm::element_numeric:
+        {
+            MatrixImplType::numeric_block_type::iterator it2 =
+                MatrixImplType::numeric_block_type::begin(*aPos2.first->data);
+
+            for (; it != itEnd; ++it, ++it2)
+                *it += *it2;
+        }
+        break;
+        default:
+            ;
+    }
+}
+
 #if DEBUG_MATRIX
 void ScMatrixImpl::Dump() const
 {
@@ -2193,6 +2249,12 @@ void ScMatrix::MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const
     pImpl->MergeDoubleArray(rArray, eOp);
 }
 
+ScMatrix& ScMatrix::operator+= ( const ScMatrix& r )
+{
+    pImpl->AddValues(*r.pImpl);
+    return *this;
+}
+
 #if DEBUG_MATRIX
 void ScMatrix::Dump() const
 {
commit 7195a5b87ca6ac22246b80cf8e907eb22f8e0f12
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Oct 17 22:55:20 2013 -0400

    No need to fill zeros here. The matrix is initialized with zeros.
    
    Change-Id: I842819ed5ee040d4c65c3676ea35707d4087602a

diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index fddd8c3..5961bc5 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5432,11 +5432,9 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
                     SCSIZE nResC, nResR;
                     nResC = nCol2 - nCol1 + 1;
                     nResR = nRow2 - nRow1 + 1;
-                    pResMat = GetNewMat(nResC, nResR);
+                    pResMat = GetNewMat(nResC, nResR, false);
                     if (!pResMat)
                         SetError( errIllegalParameter);
-                    else
-                        pResMat->FillDouble( 0.0, 0, 0, nResC-1, nResR-1);
                 }
 
                 ScQueryParam rParam;
commit b80eb0fe5869b5e8b4370e037be5eb613e0e7292
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Oct 17 22:21:01 2013 -0400

    Re-write CompareEqual etc. to make it run faster.
    
    Change-Id: I6efeff7c97695cab060319f20fae8673286a6c0a

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 96ed001..5d8cc9a2 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -136,33 +136,67 @@ struct ElemLessEqualZero : public unary_function<double, bool>
 };
 
 template<typename _Comp>
-void compareMatrix(MatrixImplType& rMat)
+class CompareMatrixElemFunc : std::unary_function<MatrixImplType::element_block_node_type, void>
 {
-    MatrixImplType::size_pair_type aDim = rMat.size();
-    MatrixImplType aNewMat(aDim.row, aDim.column, false); // initialize with boolean block.  faster this way.
+    static _Comp maComp;
 
-    _Comp aComp;
-    for (size_t i = 0; i < aDim.row; ++i)
+    MatrixImplType maNewMat;
+    std::deque<bool> maNewMatValues;
+public:
+    CompareMatrixElemFunc( size_t nRow, size_t nCol ) :
+        maNewMat(nRow, nCol, false) {}
+
+    void operator() (const MatrixImplType::element_block_node_type& node)
     {
-        for (size_t j = 0; j < aDim.column; ++j)
+        switch (node.type)
         {
-            MatrixImplType::const_position_type aPos = rMat.position(i, j);
-            mdds::mtm::element_t eType = rMat.get_type(aPos);
-            if (eType != mdds::mtm::element_numeric && eType != mdds::mtm::element_boolean)
-                // must be of numeric type (boolean can be numeric).
-                continue;
+            case mdds::mtm::element_numeric:
+            {
+                typedef MatrixImplType::numeric_block_type block_type;
 
-            double fVal = rMat.get_numeric(aPos);
-            if (!::rtl::math::isFinite(fVal))
-                /* FIXME: this silently skips an error instead of propagating it! */
-                continue;
+                block_type::const_iterator it = block_type::begin(*node.data);
+                block_type::const_iterator itEnd = block_type::end(*node.data);
+                for (; it != itEnd; ++it)
+                {
+                    double fVal = *it;
+                    if (!rtl::math::isFinite(fVal))
+                    {
+                        /* FIXME: this silently skips an error instead of propagating it! */
+                        maNewMatValues.push_back(false);
+                        continue;
+                    }
+
+                    maNewMatValues.push_back(maComp(fVal));
+                }
+            }
+            break;
+            case mdds::mtm::element_boolean:
+            {
+                typedef MatrixImplType::boolean_block_type block_type;
 
-            bool b = aComp(fVal);
-            aNewMat.set(i, j, b);
+                block_type::const_iterator it = block_type::begin(*node.data);
+                block_type::const_iterator itEnd = block_type::end(*node.data);
+                for (; it != itEnd; ++it)
+                {
+                    double fVal = *it ? 1.0 : 0.0;
+                    maNewMatValues.push_back(maComp(fVal));
+                }
+            }
+            break;
+            case mdds::mtm::element_string:
+            case mdds::mtm::element_empty:
+            default:
+                // Fill it with false.
+                maNewMatValues.resize(maNewMatValues.size() + node.size, false);
         }
     }
-    aNewMat.swap(rMat);
-}
+
+    void swap( MatrixImplType& rMat )
+    {
+        maNewMat.set(0, 0, maNewMatValues.begin(), maNewMatValues.end());
+        rMat.swap(maNewMat);
+    }
+};
 
 }
 
@@ -901,32 +935,50 @@ void ScMatrixImpl::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2,
 
 void ScMatrixImpl::CompareEqual()
 {
-    compareMatrix<ElemEqualZero>(maMat);
+    MatrixImplType::size_pair_type aSize = maMat.size();
+    CompareMatrixElemFunc<ElemEqualZero> aFunc(aSize.row, aSize.column);
+    maMat.walk(aFunc);
+    aFunc.swap(maMat);
 }
 
 void ScMatrixImpl::CompareNotEqual()
 {
-    compareMatrix<ElemNotEqualZero>(maMat);
+    MatrixImplType::size_pair_type aSize = maMat.size();
+    CompareMatrixElemFunc<ElemNotEqualZero> aFunc(aSize.row, aSize.column);
+    maMat.walk(aFunc);
+    aFunc.swap(maMat);
 }
 
 void ScMatrixImpl::CompareLess()
 {
-    compareMatrix<ElemLessZero>(maMat);
+    MatrixImplType::size_pair_type aSize = maMat.size();
+    CompareMatrixElemFunc<ElemLessZero> aFunc(aSize.row, aSize.column);
+    maMat.walk(aFunc);
+    aFunc.swap(maMat);
 }
 
 void ScMatrixImpl::CompareGreater()
 {
-    compareMatrix<ElemGreaterZero>(maMat);
+    MatrixImplType::size_pair_type aSize = maMat.size();
+    CompareMatrixElemFunc<ElemGreaterZero> aFunc(aSize.row, aSize.column);
+    maMat.walk(aFunc);
+    aFunc.swap(maMat);
 }
 
 void ScMatrixImpl::CompareLessEqual()
 {
-    compareMatrix<ElemLessEqualZero>(maMat);
+    MatrixImplType::size_pair_type aSize = maMat.size();
+    CompareMatrixElemFunc<ElemLessEqualZero> aFunc(aSize.row, aSize.column);
+    maMat.walk(aFunc);
+    aFunc.swap(maMat);
 }
 
 void ScMatrixImpl::CompareGreaterEqual()
 {
-    compareMatrix<ElemGreaterEqualZero>(maMat);
+    MatrixImplType::size_pair_type aSize = maMat.size();
+    CompareMatrixElemFunc<ElemGreaterEqualZero> aFunc(aSize.row, aSize.column);
+    maMat.walk(aFunc);
+    aFunc.swap(maMat);
 }
 
 namespace {
@@ -1357,8 +1409,6 @@ public:
 
     void operator() (const MatrixImplType::element_block_node_type& node)
     {
-        using namespace mdds::mtv;
-
         switch (node.type)
         {
             case mdds::mtm::element_numeric:
commit 335978eb36fcd6d235e652cd5319b06f2d5c7ee1
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Oct 17 21:44:35 2013 -0400

    A little cleanup. Derive block types from multi_type_matrix.
    
    Rather than directly using the blocks from mtv.
    
    Change-Id: I215e38ad406f8edc5d15c9f011dde649fce1d671

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index fbf77cd..96ed001 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -1057,8 +1057,10 @@ public:
         {
             case mdds::mtm::element_numeric:
             {
-                mdds::mtv::numeric_element_block::const_iterator it = mdds::mtv::numeric_element_block::begin(*node.data);
-                mdds::mtv::numeric_element_block::const_iterator itEnd = mdds::mtv::numeric_element_block::end(*node.data);
+                typedef MatrixImplType::numeric_block_type block_type;
+
+                block_type::const_iterator it = block_type::begin(*node.data);
+                block_type::const_iterator itEnd = block_type::end(*node.data);
                 for (; it != itEnd; ++it)
                 {
                     if (mbFirst)
@@ -1074,8 +1076,10 @@ public:
             break;
             case mdds::mtm::element_boolean:
             {
-                mdds::mtv::boolean_element_block::const_iterator it = mdds::mtv::boolean_element_block::begin(*node.data);
-                mdds::mtv::boolean_element_block::const_iterator itEnd = mdds::mtv::boolean_element_block::end(*node.data);
+                typedef MatrixImplType::boolean_block_type block_type;
+
+                block_type::const_iterator it = block_type::begin(*node.data);
+                block_type::const_iterator itEnd = block_type::end(*node.data);
                 for (; it != itEnd; ++it)
                 {
                     if (mbFirst)
@@ -1177,8 +1181,10 @@ size_t WalkAndMatchElements<double>::compare(const MatrixImplType::element_block
     {
         case mdds::mtm::element_numeric:
         {
-            MatrixImplType::numeric_block_type::const_iterator it = MatrixImplType::numeric_block_type::begin(*node.data);
-            MatrixImplType::numeric_block_type::const_iterator itEnd = MatrixImplType::numeric_block_type::end(*node.data);
+            typedef MatrixImplType::numeric_block_type block_type;
+
+            block_type::const_iterator it = block_type::begin(*node.data);
+            block_type::const_iterator itEnd = block_type::end(*node.data);
             for (; it != itEnd; ++it, nCount++)
             {
                 if (*it == maMatchValue)
@@ -1190,8 +1196,10 @@ size_t WalkAndMatchElements<double>::compare(const MatrixImplType::element_block
         }
         case mdds::mtm::element_boolean:
         {
-            MatrixImplType::boolean_block_type::const_iterator it = MatrixImplType::boolean_block_type::begin(*node.data);
-            MatrixImplType::boolean_block_type::const_iterator itEnd = MatrixImplType::boolean_block_type::end(*node.data);
+            typedef MatrixImplType::boolean_block_type block_type;
+
+            block_type::const_iterator it = block_type::begin(*node.data);
+            block_type::const_iterator itEnd = block_type::end(*node.data);
             for (; it != itEnd; ++it, ++nCount)
             {
                 if (int(*it) == maMatchValue)
@@ -1218,8 +1226,10 @@ size_t WalkAndMatchElements<svl::SharedString>::compare(const MatrixImplType::el
     {
         case mdds::mtm::element_string:
         {
-            MatrixImplType::string_block_type::const_iterator it = MatrixImplType::string_block_type::begin(*node.data);
-            MatrixImplType::string_block_type::const_iterator itEnd = MatrixImplType::string_block_type::end(*node.data);
+            typedef MatrixImplType::string_block_type block_type;
+
+            block_type::const_iterator it = block_type::begin(*node.data);
+            block_type::const_iterator itEnd = block_type::end(*node.data);
             for (; it != itEnd; ++it, ++nCount)
             {
                 if (it->getDataIgnoreCase() == maMatchValue.getDataIgnoreCase())
@@ -1247,8 +1257,8 @@ struct MaxOp
     }
 
     static double boolValue(
-        mdds::mtv::boolean_element_block::const_iterator it,
-        mdds::mtv::boolean_element_block::const_iterator itEnd)
+        MatrixImplType::boolean_block_type::const_iterator it,
+        MatrixImplType::boolean_block_type::const_iterator itEnd)
     {
         // If the array has at least one true value, the maximum value is 1.
         it = std::find(it, itEnd, true);
@@ -1265,8 +1275,8 @@ struct MinOp
     }
 
     static double boolValue(
-        mdds::mtv::boolean_element_block::const_iterator it,
-        mdds::mtv::boolean_element_block::const_iterator itEnd)
+        MatrixImplType::boolean_block_type::const_iterator it,
+        MatrixImplType::boolean_block_type::const_iterator itEnd)
     {
         // If the array has at least one false value, the minimum value is 0.
         it = std::find(it, itEnd, false);
@@ -1288,22 +1298,25 @@ public:
 
     void operator() (const MatrixImplType::element_block_node_type& node)
     {
-        using namespace mdds::mtv;
 
         switch (node.type)
         {
             case mdds::mtm::element_numeric:
             {
-                numeric_element_block::const_iterator it = numeric_element_block::begin(*node.data);
-                numeric_element_block::const_iterator itEnd = numeric_element_block::end(*node.data);
+                typedef MatrixImplType::numeric_block_type block_type;
+
+                block_type::const_iterator it = block_type::begin(*node.data);
+                block_type::const_iterator itEnd = block_type::end(*node.data);
                 for (; it != itEnd; ++it)
                     mfVal = _Op::compare(mfVal, *it);
             }
             break;
             case mdds::mtm::element_boolean:
             {
-                boolean_element_block::const_iterator it = boolean_element_block::begin(*node.data);
-                boolean_element_block::const_iterator itEnd = boolean_element_block::end(*node.data);
+                typedef MatrixImplType::boolean_block_type block_type;
+
+                block_type::const_iterator it = block_type::begin(*node.data);
+                block_type::const_iterator itEnd = block_type::end(*node.data);
                 double fVal = _Op::boolValue(it, itEnd);
                 mfVal = _Op::compare(mfVal, fVal);
             }
commit 10ccf6acde86601beb2d95c5b094cecd41beea2a
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Oct 17 21:03:12 2013 -0400

    Reduce the number of arguments. The first argument can go now.
    
    Change-Id: Id2b9ca7b6e24edc0da4735c01798ab580fba910d

diff --git a/sc/inc/compare.hxx b/sc/inc/compare.hxx
index 9ee2992..b4e4a50 100644
--- a/sc/inc/compare.hxx
+++ b/sc/inc/compare.hxx
@@ -62,7 +62,10 @@ private:
     CompareOptions& operator=( const CompareOptions & );
 };
 
-double CompareFunc( bool bIgnoreCase, const Compare& rComp, CompareOptions* pOptions = NULL );
+/** @param pOptions
+        NULL means case sensitivity document option is to be used!
+ */
+double CompareFunc( const Compare& rComp, CompareOptions* pOptions = NULL );
 
 }
 
diff --git a/sc/source/core/tool/compare.cxx b/sc/source/core/tool/compare.cxx
index ece2ff2..5f7dd12 100644
--- a/sc/source/core/tool/compare.cxx
+++ b/sc/source/core/tool/compare.cxx
@@ -38,10 +38,7 @@ CompareOptions::CompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bo
     // struct if needed.
 }
 
-/** @param pOptions
-        NULL means case sensitivity document option is to be used!
- */
-double CompareFunc( bool bIgnoreCase, const Compare& rComp, CompareOptions* pOptions )
+double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
 {
     // Keep DoubleError if encountered
     // #i40539# if bEmpty is set, bVal/nVal are uninitialized
@@ -165,7 +162,7 @@ double CompareFunc( bool bIgnoreCase, const Compare& rComp, CompareOptions* pOpt
                 fRes = (double) ScGlobal::GetCaseCollator()->compareString(
                         *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
         }
-        else if (bIgnoreCase)
+        else if (rComp.mbIgnoreCase)
             fRes = (double) ScGlobal::GetCollator()->compareString(
                 *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
         else
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 77bcb8a..fddd8c3 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -875,7 +875,7 @@ double ScInterpreter::Compare()
     if( nGlobalError )
         return 0;
     nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
-    return sc::CompareFunc(pDok->GetDocOptions().IsIgnoreCase(), aComp);
+    return sc::CompareFunc(aComp);
 }
 
 
@@ -976,7 +976,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( sc::CompareOptions* pOptions )
                                 aComp.bEmpty[i] = false;
                             }
                         }
-                        aRes.mpMat->PutDouble(sc::CompareFunc(pDok->GetDocOptions().IsIgnoreCase(), aComp, pOptions), j, k);
+                        aRes.mpMat->PutDouble(sc::CompareFunc(aComp, pOptions), j, k);
                     }
                     else
                         aRes.mpMat->PutString(mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), j, k);
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 8b45f00..fbf77cd 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -1332,7 +1332,7 @@ class CompareMatrixFunc : std::unary_function<MatrixImplType::element_block_type
 
     void compare()
     {
-        maResValues.push_back(sc::CompareFunc(mrComp.mbIgnoreCase, mrComp, mpOptions));
+        maResValues.push_back(sc::CompareFunc(mrComp, mpOptions));
     }
 
 public:
commit 60cc84c95364601190dd6c9d731d73c11dc83366
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Oct 17 21:00:00 2013 -0400

    Move the compare-matrix code to ScMatrix, for much faster execution.
    
    Change-Id: I3c4f255469b48cfd6f132503ff695e347d8ae912

diff --git a/sc/inc/compare.hxx b/sc/inc/compare.hxx
index 307b531..9ee2992 100644
--- a/sc/inc/compare.hxx
+++ b/sc/inc/compare.hxx
@@ -35,7 +35,10 @@ struct Compare
     bool bVal[2];
     bool bEmpty[2];
 
-    Compare( OUString* p1, OUString* p2 )
+    bool mbIgnoreCase;
+
+    Compare( OUString* p1, OUString* p2 ) :
+        mbIgnoreCase(true)
     {
         pVal[0] = p1;
         pVal[1] = p2;
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index edd8cbd..8317b85 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -36,6 +36,13 @@ class ScInterpreter;
 class SvNumberFormatter;
 class ScMatrixImpl;
 
+namespace sc {
+
+struct Compare;
+struct CompareOptions;
+
+}
+
 /**
  * Try NOT to use this struct.  This struct should go away in a hopefully
  * not so distant futture.
@@ -394,6 +401,9 @@ public:
     double GetMaxValue( bool bTextAsZero ) const;
     double GetMinValue( bool bTextAsZero ) const;
 
+    void CompareMatrix(
+        ScMatrix& rResMat, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions = NULL ) const;
+
     void GetDoubleArray( std::vector<double>& rArray ) const;
     void MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const;
 
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 3749dbd..77bcb8a 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -793,6 +793,7 @@ double ScInterpreter::Compare()
 {
     OUString aVal1, aVal2;
     sc::Compare aComp( &aVal1, &aVal2 );
+    aComp.mbIgnoreCase = pDok->GetDocOptions().IsIgnoreCase();
     for( short i = 1; i >= 0; i-- )
     {
         switch ( GetRawStackType() )
@@ -882,6 +883,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( sc::CompareOptions* pOptions )
 {
     OUString aVal1, aVal2;
     sc::Compare aComp( &aVal1, &aVal2 );
+    aComp.mbIgnoreCase = pDok->GetDocOptions().IsIgnoreCase();
     sc::RangeMatrix aMat[2];
     ScAddress aAdr;
     for( short i = 1; i >= 0; i-- )
@@ -983,7 +985,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( sc::CompareOptions* pOptions )
         }
         else if (aMat[0].mpMat || aMat[1].mpMat)
         {
-            short i = ( aMat[0].mpMat ? 0 : 1);
+            size_t i = ( aMat[0].mpMat ? 0 : 1);
             SCSIZE nC, nR;
             aMat[i].mpMat->GetDimensions(nC, nR);
             aRes.mpMat = GetNewMat(nC, nR, false);
@@ -999,46 +1001,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( sc::CompareOptions* pOptions )
 
             ScMatrix& rMat = *aMat[i].mpMat;
             ScMatrix& rResMat = *aRes.mpMat;
-            ScMatrix::PosRef pMatPos(rMat.GetPosition(0, 0));
-            ScMatrixValue aVal;
-            std::vector<double> aResMatValues;
-            aResMatValues.reserve(nC*nR);
-            for (size_t j = 0, n = nC*nR; j < n; ++j)
-            {
-                aVal = rMat.Get(*pMatPos);
-                switch (aVal.nType)
-                {
-                    case SC_MATVAL_VALUE:
-                    case SC_MATVAL_BOOLEAN:
-                    {
-                        aComp.bVal[i] = true;
-                        aComp.nVal[i] = aVal.fVal;
-                        aComp.bEmpty[i] = false;
-                    }
-                    break;
-                    case SC_MATVAL_STRING:
-                    {
-                        aComp.bVal[i] = false;
-                        *aComp.pVal[i] = aVal.aStr.getString();
-                        aComp.bEmpty[i] = false;
-                    }
-                    break;
-                    case SC_MATVAL_EMPTY:
-                    case SC_MATVAL_EMPTYPATH:
-                    {
-                        aComp.bVal[i] = false;
-                        *aComp.pVal[i] = svl::SharedString::getEmptyString().getString();
-                        aComp.bEmpty[i] = aVal.nType == SC_MATVAL_EMPTY;
-                    }
-                    break;
-                    default:
-                        ;
-                }
-
-                aResMatValues.push_back(sc::CompareFunc(pDok->GetDocOptions().IsIgnoreCase(), aComp, pOptions));
-                rMat.NextPosition(*pMatPos);
-            }
-            rResMat.PutDouble(&aResMatValues[0], aResMatValues.size(), 0, 0);
+            rMat.CompareMatrix(rResMat, aComp, i, pOptions);
         }
     }
     nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 164da28..8b45f00 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -23,6 +23,7 @@
 #include "formula/errorcodes.hxx"
 #include "interpre.hxx"
 #include "mtvelements.hxx"
+#include "compare.hxx"
 
 #include <svl/zforlist.hxx>
 #include "svl/sharedstring.hxx"
@@ -264,6 +265,9 @@ public:
 
     double GetMaxValue( bool bTextAsZero ) const;
     double GetMinValue( bool bTextAsZero ) const;
+
+    void CompareMatrix( ScMatrix& rResMat, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) const;
+
     void GetDoubleArray( std::vector<double>& rArray ) const;
     void MergeDoubleArray( std::vector<double>& rArray, ScMatrix::Op eOp ) const;
 
@@ -1318,6 +1322,97 @@ public:
     }
 };
 
+class CompareMatrixFunc : std::unary_function<MatrixImplType::element_block_type, void>
+{
+    sc::Compare& mrComp;
+    size_t mnMatPos;
+    sc::CompareOptions* mpOptions;
+
+    std::vector<double> maResValues;
+
+    void compare()
+    {
+        maResValues.push_back(sc::CompareFunc(mrComp.mbIgnoreCase, mrComp, mpOptions));
+    }
+
+public:
+    CompareMatrixFunc( size_t nResSize, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) :
+        mrComp(rComp), mnMatPos(nMatPos), mpOptions(pOptions)
+    {
+        maResValues.reserve(nResSize);
+    }
+
+    void operator() (const MatrixImplType::element_block_node_type& node)
+    {
+        using namespace mdds::mtv;
+
+        switch (node.type)
+        {
+            case mdds::mtm::element_numeric:
+            {
+                typedef MatrixImplType::numeric_block_type block_type;
+
+                block_type::const_iterator it = block_type::begin(*node.data);
+                block_type::const_iterator itEnd = block_type::end(*node.data);
+                for (; it != itEnd; ++it)
+                {
+                    mrComp.bVal[mnMatPos] = true;
+                    mrComp.nVal[mnMatPos] = *it;
+                    mrComp.bEmpty[mnMatPos] = false;
+                    compare();
+                }
+            }
+            break;
+            case mdds::mtm::element_boolean:
+            {
+                typedef MatrixImplType::boolean_block_type block_type;
+
+                block_type::const_iterator it = block_type::begin(*node.data);
+                block_type::const_iterator itEnd = block_type::end(*node.data);
+                for (; it != itEnd; ++it)
+                {
+                    mrComp.bVal[mnMatPos] = true;
+                    mrComp.nVal[mnMatPos] = *it;
+                    mrComp.bEmpty[mnMatPos] = false;
+                    compare();
+                }
+            }
+            break;
+            case mdds::mtm::element_string:
+            {
+                typedef MatrixImplType::string_block_type block_type;
+
+                block_type::const_iterator it = block_type::begin(*node.data);
+                block_type::const_iterator itEnd = block_type::end(*node.data);
+                for (; it != itEnd; ++it)
+                {
+                    const svl::SharedString& rStr = *it;
+                    mrComp.bVal[mnMatPos] = false;
+                    *mrComp.pVal[mnMatPos] = rStr.getString();
+                    mrComp.bEmpty[mnMatPos] = false;
+                    compare();
+                }
+            }
+            break;
+            case mdds::mtm::element_empty:
+            {
+                mrComp.bVal[mnMatPos] = false;
+                *mrComp.pVal[mnMatPos] = svl::SharedString::getEmptyString().getString();
+                mrComp.bEmpty[mnMatPos] = true;
+                for (size_t i = 0; i < node.size; ++i)
+                    compare();
+            }
+            default:
+                ;
+        }
+    }
+
+    const std::vector<double>& getValues() const
+    {
+        return maResValues;
+    }
+};
+
 class ToDoubleArray : std::unary_function<MatrixImplType::element_block_type, void>
 {
     std::vector<double> maArray;
@@ -1496,6 +1591,20 @@ double ScMatrixImpl::GetMinValue( bool bTextAsZero ) const
     return aFunc.getValue();
 }
 
+void ScMatrixImpl::CompareMatrix(
+    ScMatrix& rResMat, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) const
+{
+    MatrixImplType::size_pair_type aSize = maMat.size();
+    size_t nSize = aSize.column * aSize.row;
+    CompareMatrixFunc aFunc(nSize, rComp, nMatPos, pOptions);
+    maMat.walk(aFunc);
+
+    // We assume the result matrix has the same dimension as this matrix.
+    const std::vector<double>& rResVal = aFunc.getValues();
+    if (nSize == rResVal.size())
+        rResMat.PutDouble(&rResVal[0], rResVal.size(), 0, 0);
+}
+
 void ScMatrixImpl::GetDoubleArray( std::vector<double>& rArray ) const
 {
     MatrixImplType::size_pair_type aSize = maMat.size();
@@ -2006,6 +2115,11 @@ double ScMatrix::GetMinValue( bool bTextAsZero ) const
     return pImpl->GetMinValue(bTextAsZero);
 }
 
+void ScMatrix::CompareMatrix( ScMatrix& rResMat, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) const
+{
+    pImpl->CompareMatrix(rResMat, rComp, nMatPos, pOptions);
+}
+
 void ScMatrix::GetDoubleArray( std::vector<double>& rArray ) const
 {
     pImpl->GetDoubleArray(rArray);
commit 4162c889f228593861965ecca732dbec01d82731
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Oct 17 19:43:01 2013 -0400

    Fix brace styles.
    
    Change-Id: Ieb169d5ef8700067fbf011bbfc18fca6b40c03b8

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 4b3bbc3..164da28 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -1986,11 +1986,13 @@ size_t ScMatrix::Count(bool bCountStrings) const
     return pImpl->Count(bCountStrings);
 }
 
-size_t ScMatrix::MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const {
+size_t ScMatrix::MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const
+{
     return pImpl->MatchDoubleInColumns(fValue, nCol1, nCol2);
 }
 
-size_t ScMatrix::MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const {
+size_t ScMatrix::MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const
+{
     return pImpl->MatchStringInColumns(rStr, nCol1, nCol2);
 }
 
commit e09cedd92259d8fdb98a7591b46a813685f0df96
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Oct 17 19:23:01 2013 -0400

    Initial attempt to speed up matrix comparison.
    
    And move the value compare code to somewhere public.  I'll be using it
    from the ScMatrix internal.
    
    This change requires mdds 0.9.1 which is yet to be released.
    
    Change-Id: I942133c85b614b3404006fa38af111ace9361fd4

diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index f76032a..3cd88db 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -195,6 +195,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
 	sc/source/core/tool/chartpos \
 	sc/source/core/tool/chgtrack \
 	sc/source/core/tool/chgviset \
+	sc/source/core/tool/compare \
 	sc/source/core/tool/compiler \
 	sc/source/core/tool/consoli  \
 	sc/source/core/tool/dbdata \
diff --git a/sc/inc/compare.hxx b/sc/inc/compare.hxx
new file mode 100644
index 0000000..307b531
--- /dev/null
+++ b/sc/inc/compare.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef SC_COMPARE_HXX
+#define SC_COMPARE_HXX
+
+#include "queryentry.hxx"
+
+#include "rtl/ustring.hxx"
+
+class ScDocument;
+
+namespace sc {
+
+struct Compare
+{
+    double nVal[2];
+    OUString* pVal[2];
+    bool bVal[2];
+    bool bEmpty[2];
+
+    Compare( OUString* p1, OUString* p2 )
+    {
+        pVal[0] = p1;
+        pVal[1] = p2;
+        bEmpty[0] = false;
+        bEmpty[1] = false;
+    }
+};
+
+struct CompareOptions
+{
+    ScQueryEntry        aQueryEntry;
+    bool                bRegEx;
+    bool                bMatchWholeCell;
+    bool                bIgnoreCase;
+
+    CompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg );
+private:
+    // Not implemented, prevent usage.
+    CompareOptions();
+    CompareOptions( const CompareOptions & );
+    CompareOptions& operator=( const CompareOptions & );
+};
+
+double CompareFunc( bool bIgnoreCase, const Compare& rComp, CompareOptions* pOptions = NULL );
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index b997506..edd8cbd 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -25,8 +25,10 @@
 #include "formula/errorcodes.hxx"
 #include "scdllapi.h"
 #include <rtl/ustring.hxx>
+#include "svl/sharedstring.hxx"
 
 #include <boost/intrusive_ptr.hpp>
+#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
 
 #define DEBUG_MATRIX 0
 
@@ -34,8 +36,6 @@ class ScInterpreter;
 class SvNumberFormatter;
 class ScMatrixImpl;
 
-namespace svl { class SharedString; }
-
 /**
  * Try NOT to use this struct.  This struct should go away in a hopefully
  * not so distant futture.
@@ -43,11 +43,11 @@ namespace svl { class SharedString; }
 struct ScMatrixValue
 {
     double fVal;
-    OUString aStr;
+    svl::SharedString aStr;
     ScMatValType nType;
 
     /// Only valid if ScMatrix methods indicate so!
-    const OUString& GetString() const { return aStr; }
+    OUString GetString() const { return aStr.getString(); }
 
     /// Only valid if ScMatrix methods indicate that this is no string!
     sal_uInt16 GetError() const         { return GetDoubleErrorValue( fVal); }
@@ -137,6 +137,31 @@ public:
             mfFirst(r.mfFirst), mfRest(r.mfRest), mnCount(r.mnCount) {}
     };
 
+    struct Pos;
+    struct ConstPos;
+
+    static void DeletePosition( const Pos* p );
+    static void DeletePosition( const ConstPos* p );
+
+    struct PosDeleter : std::unary_function<const Pos*, void>
+    {
+        void operator() (const Pos* p)
+        {
+            DeletePosition(p);
+        }
+    };
+
+    struct ConstPosDeleter : std::unary_function<const ConstPos*, void>
+    {
+        void operator() (const ConstPos* p)
+        {
+            DeletePosition(p);
+        }
+    };
+
+    typedef boost::interprocess::unique_ptr<Pos, PosDeleter> PosRef;
+    typedef boost::interprocess::unique_ptr<ConstPos, PosDeleter> ConstPosRef;
+
     /// The maximum number of elements a matrix may have at runtime.
     inline static size_t GetElementsMax()
     {
@@ -289,6 +314,8 @@ public:
     /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate
     /// an empty string!
     ScMatrixValue Get( SCSIZE nC, SCSIZE nR) const;
+    ScMatrixValue Get( const Pos& rPos ) const;
+    ScMatrixValue Get( const ConstPos& rPos ) const;
 
     /// @return <TRUE/> if string or empty or empty path, in fact non-value.
     sal_Bool IsString( SCSIZE nIndex ) const;
@@ -317,6 +344,31 @@ public:
     /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties
     sal_Bool IsNumeric() const;
 
+    Pos* GetPosition( size_t nC, size_t nR );
+    ConstPos* GetConstPosition( size_t nC, size_t nR ) const;
+
+    bool NextPosition( Pos& rPos );
+    bool NextPosition( ConstPos& rPos ) const;
+
+    bool IsValue( const Pos& rPos ) const;
+    bool IsValue( const ConstPos& rPos ) const;
+
+    bool IsEmpty( const Pos& rPos ) const;
+    bool IsEmpty( const ConstPos& rPos ) const;
+
+    double GetDouble( const Pos& rPos ) const;
+    double GetDouble( const ConstPos& rPos ) const;
+
+    svl::SharedString GetString( const Pos& rPos ) const;
+    svl::SharedString GetString( const ConstPos& rPos ) const;
+
+    void PutDouble( double fVal, Pos& rPos );
+    void PutString( const svl::SharedString& rStr, Pos& rPos );
+    void PutEmpty( Pos& rPos );
+    void PutEmptyPath( Pos& rPos );
+    void PutError( sal_uInt16 nErr, Pos& rPos );
+    void PutBoolean( bool bVal, Pos& rPos );
+
     void MatTrans( ScMatrix& mRes) const;
     void MatCopy ( ScMatrix& mRes) const;
 
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index bdcbbd0..b387170 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -1458,7 +1458,7 @@ struct PartiallyFilledEmptyMatrix
         else if (nCol == 8 && nRow == 2)
         {
             CPPUNIT_ASSERT_MESSAGE("element is not of value type", rVal.nType == SC_MATVAL_STRING);
-            CPPUNIT_ASSERT_MESSAGE("element value is not what is expected", rVal.aStr == "Test");
+            CPPUNIT_ASSERT_MESSAGE("element value is not what is expected", rVal.aStr.getString() == "Test");
         }
         else if (nCol == 8 && nRow == 11)
         {
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 304f841..11adc34 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -42,8 +42,6 @@ struct ScQueryParam;
 struct ScDBQueryParamBase;
 struct ScQueryEntry;
 
-struct ScCompare;
-struct ScCompareOptions;
 struct ScSingleRefData;
 struct ScComplexRefData;
 
@@ -54,6 +52,8 @@ struct ScRefCellValue;
 namespace sc {
 
 struct RangeMatrix;
+struct Compare;
+struct CompareOptions;
 
 }
 
@@ -382,16 +382,12 @@ void ScChoseJump();
 // Returns true if last jump was executed and result matrix pushed.
 bool JumpMatrix( short nStackLevel );
 
-/** @param pOptions
-        NULL means case sensitivity document option is to be used!
- */
-double CompareFunc( const ScCompare& rComp, ScCompareOptions* pOptions = NULL );
 double Compare();
 /** @param pOptions
         NULL means case sensitivity document option is to be used!
  */
-sc::RangeMatrix CompareMat( ScCompareOptions* pOptions = NULL );
-ScMatrixRef QueryMat( const ScMatrixRef& pMat, ScCompareOptions& rOptions );
+sc::RangeMatrix CompareMat( sc::CompareOptions* pOptions = NULL );
+ScMatrixRef QueryMat( const ScMatrixRef& pMat, sc::CompareOptions& rOptions );
 void ScEqual();
 void ScNotEqual();
 void ScLess();
diff --git a/sc/source/core/tool/compare.cxx b/sc/source/core/tool/compare.cxx
new file mode 100644
index 0000000..ece2ff2
--- /dev/null
+++ b/sc/source/core/tool/compare.cxx
@@ -0,0 +1,201 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "compare.hxx"
+
+#include "document.hxx"
+#include "docoptio.hxx"
+
+#include "unotools/textsearch.hxx"
+
+namespace sc {
+
+CompareOptions::CompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg ) :
+    aQueryEntry(rEntry),
+    bRegEx(bReg),
+    bMatchWholeCell(pDoc->GetDocOptions().IsMatchWholeCell()),
+    bIgnoreCase(true)
+{
+    bRegEx = (bRegEx && (aQueryEntry.eOp == SC_EQUAL || aQueryEntry.eOp == SC_NOT_EQUAL));
+    // Interpreter functions usually are case insensitive, except the simple
+    // comparison operators, for which these options aren't used. Override in
+    // struct if needed.
+}
+
+/** @param pOptions
+        NULL means case sensitivity document option is to be used!
+ */
+double CompareFunc( bool bIgnoreCase, const Compare& rComp, CompareOptions* pOptions )
+{
+    // Keep DoubleError if encountered
+    // #i40539# if bEmpty is set, bVal/nVal are uninitialized
+    if ( !rComp.bEmpty[0] && rComp.bVal[0] && !::rtl::math::isFinite( rComp.nVal[0]))
+        return rComp.nVal[0];
+    if ( !rComp.bEmpty[1] && rComp.bVal[1] && !::rtl::math::isFinite( rComp.nVal[1]))
+        return rComp.nVal[1];
+
+    size_t nStringQuery = 0;    // 0:=no, 1:=0, 2:=1
+    double fRes = 0;
+    if ( rComp.bEmpty[ 0 ] )
+    {
+        if ( rComp.bEmpty[ 1 ] )
+            ;       // empty cell == empty cell, fRes 0
+        else if( rComp.bVal[ 1 ] )
+        {
+            if ( !::rtl::math::approxEqual( rComp.nVal[ 1 ], 0.0 ) )
+            {
+                if ( rComp.nVal[ 1 ] < 0.0 )
+                    fRes = 1;       // empty cell > -x
+                else
+                    fRes = -1;      // empty cell < x
+            }
+            // else: empty cell == 0.0
+        }
+        else
+        {
+            if ( !rComp.pVal[ 1 ]->isEmpty() )
+                fRes = -1;      // empty cell < "..."
+            // else: empty cell == ""
+        }
+    }
+    else if ( rComp.bEmpty[ 1 ] )
+    {
+        if( rComp.bVal[ 0 ] )
+        {
+            if ( !::rtl::math::approxEqual( rComp.nVal[ 0 ], 0.0 ) )
+            {
+                if ( rComp.nVal[ 0 ] < 0.0 )
+                    fRes = -1;      // -x < empty cell
+                else
+                    fRes = 1;       // x > empty cell
+            }
+            // else: empty cell == 0.0
+        }
+        else
+        {
+            if ( !rComp.pVal[ 0 ]->isEmpty() )
+                fRes = 1;       // "..." > empty cell
+            // else: "" == empty cell
+        }
+    }
+    else if( rComp.bVal[ 0 ] )
+    {
+        if( rComp.bVal[ 1 ] )
+        {
+            if ( !::rtl::math::approxEqual( rComp.nVal[ 0 ], rComp.nVal[ 1 ] ) )
+            {
+                if( rComp.nVal[ 0 ] - rComp.nVal[ 1 ] < 0 )
+                    fRes = -1;
+                else
+                    fRes = 1;
+            }
+        }
+        else
+        {
+            fRes = -1;          // number is less than string
+            nStringQuery = 2;   // 1+1
+        }
+    }
+    else if( rComp.bVal[ 1 ] )
+    {
+        fRes = 1;               // string is greater than number
+        nStringQuery = 1;       // 0+1
+    }
+    else
+    {
+        // Both strings.
+        if (pOptions)
+        {
+            // All similar to ScTable::ValidQuery(), *rComp.pVal[1] actually
+            // is/must be identical to *rEntry.pStr, which is essential for
+            // regex to work through GetSearchTextPtr().
+            ScQueryEntry& rEntry = pOptions->aQueryEntry;
+            OSL_ENSURE(rEntry.GetQueryItem().maString.getString().equals(*rComp.pVal[1]), "ScInterpreter::CompareFunc: broken options");
+            if (pOptions->bRegEx)
+            {
+                sal_Int32 nStart = 0;
+                sal_Int32 nStop  = rComp.pVal[0]->getLength();
+                bool bMatch = rEntry.GetSearchTextPtr(
+                        !pOptions->bIgnoreCase)->SearchForward( *rComp.pVal[0],
+                            &nStart, &nStop);
+                if (bMatch && pOptions->bMatchWholeCell && (nStart != 0 || nStop != rComp.pVal[0]->getLength()))
+                    bMatch = false;     // RegEx must match entire string.
+                fRes = (bMatch ? 0 : 1);
+            }
+            else if (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL)
+            {
+                ::utl::TransliterationWrapper* pTransliteration =
+                    (pOptions->bIgnoreCase ? ScGlobal::GetpTransliteration() :
+                     ScGlobal::GetCaseTransliteration());
+                bool bMatch;
+                if (pOptions->bMatchWholeCell)
+                    bMatch = pTransliteration->isEqual( *rComp.pVal[0], *rComp.pVal[1]);
+                else
+                {
+                    OUString aCell( pTransliteration->transliterate(
+                                *rComp.pVal[0], ScGlobal::eLnge, 0,
+                                rComp.pVal[0]->getLength(), NULL));
+                    OUString aQuer( pTransliteration->transliterate(
+                                *rComp.pVal[1], ScGlobal::eLnge, 0,
+                                rComp.pVal[1]->getLength(), NULL));
+                    bMatch = (aCell.indexOf( aQuer ) != -1);
+                }
+                fRes = (bMatch ? 0 : 1);
+            }
+            else if (pOptions->bIgnoreCase)
+                fRes = (double) ScGlobal::GetCollator()->compareString(
+                        *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+            else
+                fRes = (double) ScGlobal::GetCaseCollator()->compareString(
+                        *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+        }
+        else if (bIgnoreCase)
+            fRes = (double) ScGlobal::GetCollator()->compareString(
+                *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+        else
+            fRes = (double) ScGlobal::GetCaseCollator()->compareString(
+                *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+    }
+
+    if (nStringQuery && pOptions)
+    {
+        const ScQueryEntry& rEntry = pOptions->aQueryEntry;
+        const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
+        if (!rItems.empty())
+        {
+            const ScQueryEntry::Item& rItem = rItems[0];
+            if (rItem.meType != ScQueryEntry::ByString && !rItem.maString.isEmpty() &&
+                (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL))
+            {
+                // As in ScTable::ValidQuery() match a numeric string for a
+                // number query that originated from a string, e.g. in SUMIF
+                // and COUNTIF. Transliteration is not needed here.
+                bool bEqual = (*rComp.pVal[nStringQuery-1]) == rItem.maString.getString();
+                // match => fRes=0, else fRes=1
+                fRes = (rEntry.eOp == SC_NOT_EQUAL) ? bEqual : !bEqual;
+            }
+        }
+    }
+
+    return fRes;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index f8b31f2..3749dbd 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -57,6 +57,7 @@
 #include "queryparam.hxx"
 #include "queryentry.hxx"
 #include "tokenarray.hxx"
+#include "compare.hxx"
 
 #include <comphelper/processfactory.hxx>
 #include <comphelper/string.hxx>
@@ -81,41 +82,6 @@ bool ScInterpreter::bGlobalStackInUse = false;
 using namespace formula;
 using ::std::auto_ptr;
 
-struct ScCompare
-{
-    double  nVal[2];
-    OUString* pVal[2];
-    bool    bVal[2];
-    bool    bEmpty[2];
-        ScCompare( OUString* p1, OUString* p2 )
-        {
-            pVal[ 0 ] = p1;
-            pVal[ 1 ] = p2;
-            bEmpty[0] = false;
-            bEmpty[1] = false;
-        }
-};
-
-struct ScCompareOptions
-{
-    ScQueryEntry        aQueryEntry;
-    bool                bRegEx;
-    bool                bMatchWholeCell;
-    bool                bIgnoreCase;
-
-                        ScCompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg );
-private:
-                        // Not implemented, prevent usage.
-                        ScCompareOptions();
-                        ScCompareOptions( const ScCompareOptions & );
-     ScCompareOptions&  operator=( const ScCompareOptions & );
-};
-
-//-----------------------------------------------------------------------------
-// Functions
-//-----------------------------------------------------------------------------
-
-
 void ScInterpreter::ScIfJump()
 {
     const short* pJump = pCur->GetJump();
@@ -823,180 +789,10 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
     return false;
 }
 
-
-ScCompareOptions::ScCompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg ) :
-    aQueryEntry(rEntry),
-    bRegEx(bReg),
-    bMatchWholeCell(pDoc->GetDocOptions().IsMatchWholeCell()),
-    bIgnoreCase(true)
-{
-    bRegEx = (bRegEx && (aQueryEntry.eOp == SC_EQUAL || aQueryEntry.eOp == SC_NOT_EQUAL));
-    // Interpreter functions usually are case insensitive, except the simple
-    // comparison operators, for which these options aren't used. Override in
-    // struct if needed.
-}
-
-
-double ScInterpreter::CompareFunc( const ScCompare& rComp, ScCompareOptions* pOptions )
-{
-    // Keep DoubleError if encountered
-    // #i40539# if bEmpty is set, bVal/nVal are uninitialized
-    if ( !rComp.bEmpty[0] && rComp.bVal[0] && !::rtl::math::isFinite( rComp.nVal[0]))
-        return rComp.nVal[0];
-    if ( !rComp.bEmpty[1] && rComp.bVal[1] && !::rtl::math::isFinite( rComp.nVal[1]))
-        return rComp.nVal[1];
-
-    size_t nStringQuery = 0;    // 0:=no, 1:=0, 2:=1
-    double fRes = 0;
-    if ( rComp.bEmpty[ 0 ] )
-    {
-        if ( rComp.bEmpty[ 1 ] )
-            ;       // empty cell == empty cell, fRes 0
-        else if( rComp.bVal[ 1 ] )
-        {
-            if ( !::rtl::math::approxEqual( rComp.nVal[ 1 ], 0.0 ) )
-            {
-                if ( rComp.nVal[ 1 ] < 0.0 )
-                    fRes = 1;       // empty cell > -x
-                else
-                    fRes = -1;      // empty cell < x
-            }
-            // else: empty cell == 0.0
-        }
-        else
-        {
-            if ( !rComp.pVal[ 1 ]->isEmpty() )
-                fRes = -1;      // empty cell < "..."
-            // else: empty cell == ""
-        }
-    }
-    else if ( rComp.bEmpty[ 1 ] )
-    {
-        if( rComp.bVal[ 0 ] )
-        {
-            if ( !::rtl::math::approxEqual( rComp.nVal[ 0 ], 0.0 ) )
-            {
-                if ( rComp.nVal[ 0 ] < 0.0 )
-                    fRes = -1;      // -x < empty cell
-                else
-                    fRes = 1;       // x > empty cell
-            }
-            // else: empty cell == 0.0
-        }
-        else
-        {
-            if ( !rComp.pVal[ 0 ]->isEmpty() )
-                fRes = 1;       // "..." > empty cell
-            // else: "" == empty cell
-        }
-    }
-    else if( rComp.bVal[ 0 ] )
-    {
-        if( rComp.bVal[ 1 ] )
-        {
-            if ( !::rtl::math::approxEqual( rComp.nVal[ 0 ], rComp.nVal[ 1 ] ) )
-            {
-                if( rComp.nVal[ 0 ] - rComp.nVal[ 1 ] < 0 )
-                    fRes = -1;
-                else
-                    fRes = 1;
-            }
-        }
-        else
-        {
-            fRes = -1;          // number is less than string
-            nStringQuery = 2;   // 1+1
-        }
-    }
-    else if( rComp.bVal[ 1 ] )
-    {
-        fRes = 1;               // string is greater than number
-        nStringQuery = 1;       // 0+1
-    }
-    else
-    {
-        // Both strings.
-        if (pOptions)
-        {
-            // All similar to ScTable::ValidQuery(), *rComp.pVal[1] actually
-            // is/must be identical to *rEntry.pStr, which is essential for
-            // regex to work through GetSearchTextPtr().
-            ScQueryEntry& rEntry = pOptions->aQueryEntry;
-            OSL_ENSURE(rEntry.GetQueryItem().maString.getString().equals(*rComp.pVal[1]), "ScInterpreter::CompareFunc: broken options");
-            if (pOptions->bRegEx)
-            {
-                sal_Int32 nStart = 0;
-                sal_Int32 nStop  = rComp.pVal[0]->getLength();
-                bool bMatch = rEntry.GetSearchTextPtr(
-                        !pOptions->bIgnoreCase)->SearchForward( *rComp.pVal[0],
-                            &nStart, &nStop);
-                if (bMatch && pOptions->bMatchWholeCell && (nStart != 0 || nStop != rComp.pVal[0]->getLength()))
-                    bMatch = false;     // RegEx must match entire string.
-                fRes = (bMatch ? 0 : 1);
-            }
-            else if (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL)
-            {
-                ::utl::TransliterationWrapper* pTransliteration =
-                    (pOptions->bIgnoreCase ? ScGlobal::GetpTransliteration() :
-                     ScGlobal::GetCaseTransliteration());
-                bool bMatch;
-                if (pOptions->bMatchWholeCell)
-                    bMatch = pTransliteration->isEqual( *rComp.pVal[0], *rComp.pVal[1]);
-                else
-                {
-                    OUString aCell( pTransliteration->transliterate(
-                                *rComp.pVal[0], ScGlobal::eLnge, 0,
-                                rComp.pVal[0]->getLength(), NULL));
-                    OUString aQuer( pTransliteration->transliterate(
-                                *rComp.pVal[1], ScGlobal::eLnge, 0,
-                                rComp.pVal[1]->getLength(), NULL));
-                    bMatch = (aCell.indexOf( aQuer ) != -1);
-                }
-                fRes = (bMatch ? 0 : 1);
-            }
-            else if (pOptions->bIgnoreCase)
-                fRes = (double) ScGlobal::GetCollator()->compareString(
-                        *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
-            else
-                fRes = (double) ScGlobal::GetCaseCollator()->compareString(
-                        *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
-        }
-        else if (pDok->GetDocOptions().IsIgnoreCase())
-            fRes = (double) ScGlobal::GetCollator()->compareString(
-                *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
-        else
-            fRes = (double) ScGlobal::GetCaseCollator()->compareString(
-                *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
-    }
-
-    if (nStringQuery && pOptions)
-    {
-        const ScQueryEntry& rEntry = pOptions->aQueryEntry;
-        const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
-        if (!rItems.empty())
-        {
-            const ScQueryEntry::Item& rItem = rItems[0];
-            if (rItem.meType != ScQueryEntry::ByString && !rItem.maString.isEmpty() &&
-                (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL))
-            {
-                // As in ScTable::ValidQuery() match a numeric string for a
-                // number query that originated from a string, e.g. in SUMIF
-                // and COUNTIF. Transliteration is not needed here.
-                bool bEqual = (*rComp.pVal[nStringQuery-1]) == rItem.maString.getString();
-                // match => fRes=0, else fRes=1
-                fRes = (rEntry.eOp == SC_NOT_EQUAL) ? bEqual : !bEqual;
-            }
-        }
-    }
-
-    return fRes;
-}
-
-
 double ScInterpreter::Compare()
 {
     OUString aVal1, aVal2;
-    ScCompare aComp( &aVal1, &aVal2 );
+    sc::Compare aComp( &aVal1, &aVal2 );
     for( short i = 1; i >= 0; i-- )
     {
         switch ( GetRawStackType() )
@@ -1078,14 +874,14 @@ double ScInterpreter::Compare()
     if( nGlobalError )
         return 0;
     nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
-    return CompareFunc( aComp );
+    return sc::CompareFunc(pDok->GetDocOptions().IsIgnoreCase(), aComp);
 }
 
 
-sc::RangeMatrix ScInterpreter::CompareMat( ScCompareOptions* pOptions )
+sc::RangeMatrix ScInterpreter::CompareMat( sc::CompareOptions* pOptions )
 {
     OUString aVal1, aVal2;
-    ScCompare aComp( &aVal1, &aVal2 );
+    sc::Compare aComp( &aVal1, &aVal2 );
     sc::RangeMatrix aMat[2];
     ScAddress aAdr;
     for( short i = 1; i >= 0; i-- )
@@ -1178,7 +974,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( ScCompareOptions* pOptions )
                                 aComp.bEmpty[i] = false;
                             }
                         }
-                        aRes.mpMat->PutDouble(CompareFunc(aComp, pOptions), j, k);
+                        aRes.mpMat->PutDouble(sc::CompareFunc(pDok->GetDocOptions().IsIgnoreCase(), aComp, pOptions), j, k);
                     }
                     else
                         aRes.mpMat->PutString(mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), j, k);
@@ -1190,7 +986,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( ScCompareOptions* pOptions )

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list