tdf#113112 insert a new sheet slow

We were spending vast amounts of time in ScColumn::EndListening calling
set_empty on the mdds_vector, which moved the block data around.

So walk backwards through the data, which means we will delete from the
end, and largely avoid any expensive moving around.

Change-Id: I78cbecedf137972fb2a1b7042635f4e7b03d77ff
Reviewed-on: https://gerrit.libreoffice.org/74738
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/sc/inc/mtvcellfunc.hxx b/sc/inc/mtvcellfunc.hxx
index 145d1ee..562d003 100644
--- a/sc/inc/mtvcellfunc.hxx
+++ b/sc/inc/mtvcellfunc.hxx
@@ -119,8 +119,10 @@
template<typename Func>
void ProcessFormulaEditText(CellStoreType& rStore, Func& rFunc)
{
    // Walk backwards through the data - this helps when the FuncElem will be deleting
    // stuff, so we don't continually move block data around.
    FuncElseNoOp<size_t> aElse;
    ProcessElements2<CellStoreType, edittext_block, formula_block, Func, FuncElseNoOp<size_t> >(rStore, rFunc, aElse);
    ProcessElements2Reverse<CellStoreType, edittext_block, formula_block, Func, FuncElseNoOp<size_t> >(rStore, rFunc, aElse);
}

template<typename Func>
diff --git a/sc/inc/mtvfunctions.hxx b/sc/inc/mtvfunctions.hxx
index f9052ed..5e48bb2 100644
--- a/sc/inc/mtvfunctions.hxx
+++ b/sc/inc/mtvfunctions.hxx
@@ -113,8 +113,18 @@
template<typename BlkT, typename ItrT, typename NodeT, typename FuncElem>
void EachElem(NodeT& rNode, FuncElem& rFuncElem)
{
    ItrT it = BlkT::begin(*rNode.data);
    ItrT itEnd = BlkT::end(*rNode.data);
    auto it = BlkT::begin(*rNode.data);
    auto itEnd = BlkT::end(*rNode.data);
    size_t nRow = rNode.position;
    for (; it != itEnd; ++it, ++nRow)
        rFuncElem(nRow, *it);
}

template<typename BlkT, typename ItrT, typename NodeT, typename FuncElem>
void EachElemReverse(NodeT& rNode, FuncElem& rFuncElem)
{
    auto it = BlkT::rbegin(*rNode.data);
    auto itEnd = BlkT::rend(*rNode.data);
    size_t nRow = rNode.position;
    for (; it != itEnd; ++it, ++nRow)
        rFuncElem(nRow, *it);
@@ -374,6 +384,28 @@
    }
}

template<typename StoreT, typename Blk1, typename Blk2, typename FuncElem, typename FuncElse>
void ProcessElements2Reverse(StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse)
{
    typename StoreT::size_type nTopRow = 0, nDataSize = 0;
    typename StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
    for (; it != itEnd; ++it, nTopRow += nDataSize)
    {
        nDataSize = it->size;
        switch (it->type)
        {
            case Blk1::block_type:
                EachElemReverse<Blk1, typename Blk1::iterator>(*it, rFuncElem);
            break;
            case Blk2::block_type:
                EachElemReverse<Blk2, typename Blk2::iterator>(*it, rFuncElem);
            break;
            default:
                rFuncElse(it->type, nTopRow, nDataSize);
        }
    }
}

template<typename StoreT, typename Blk1, typename FuncElem, typename FuncElse>
std::pair<typename StoreT::const_iterator, typename StoreT::size_type>
FindElement1(