Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sc/inc/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 18 kB image not shown  

Quelle  mtvfunctions.hxx

  Sprache: C
 

/* -*- 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/.
 */


#pragma once

#include <cstdlib>
#include <mdds/multi_type_vector/types.hpp>

namespace sc {

template<typename SizeT, typename Ret = bool>
struct FuncElseNoOp
{
    Ret operator() (mdds::mtv::element_t, SizeT, SizeT) const
    {
        return Ret();
    }
};

template<typename FuncElem, typename Elem>
struct FuncNotElem
{
    FuncElem& func;
    FuncNotElem(FuncElem& f) : func(f) {}
    bool operator() (size_t s, Elem elem) const
    {
        return !func(s, elem);
    }
};

/**
 * Generic algorithm to parse blocks of multi_type_vector either partially
 * or fully.
 */

template<typename StoreT, typename Func>
typename StoreT::const_iterator
ParseBlock(
    const typename StoreT::const_iterator& itPos, const StoreT& rStore, Func& rFunc,
    typename StoreT::size_type nStart, typename StoreT::size_type nEnd)
{
    typedef std::pair<typename StoreT::const_iterator, typename StoreT::size_type> PositionType;

    PositionType aPos = rStore.position(itPos, nStart);
    typename StoreT::const_iterator it = aPos.first;
    typename StoreT::size_type nOffset = aPos.second;
    typename StoreT::size_type nDataSize = 0;
    typename StoreT::size_type nTopRow = nStart;

    for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
    {
        bool bLastBlock = false;
        nDataSize = it->size - nOffset;
        if (nTopRow + nDataSize - 1 > nEnd)
        {
            // Truncate the block.
            nDataSize = nEnd - nTopRow + 1;
            bLastBlock = true;
        }

        rFunc(*it, nOffset, nDataSize);

        if (bLastBlock)
            break;
    }

    return it;
}

/**
 * Non-const variant of the above function. TODO: Find a way to merge these
 * two in an elegant way.
 */

template<typename StoreT, typename Func>
typename StoreT::iterator
ProcessBlock(const typename StoreT::iterator& itPos, StoreT& rStore, Func& rFunc, typename StoreT::size_type nStart, typename StoreT::size_type nEnd)
{
    typedef std::pair<typename StoreT::iterator, typename StoreT::size_type> PositionType;

    PositionType aPos = rStore.position(itPos, nStart);
    typename StoreT::iterator it = aPos.first;
    typename StoreT::size_type nOffset = aPos.second;
    typename StoreT::size_type nDataSize = 0;
    typename StoreT::size_type nCurRow = nStart;

    for (; it != rStore.end() && nCurRow <= nEnd; ++it, nOffset = 0, nCurRow += nDataSize)
    {
        bool bLastBlock = false;
        nDataSize = it->size - nOffset;
        if (nCurRow + nDataSize - 1 > nEnd)
        {
            // Truncate the block.
            nDataSize = nEnd - nCurRow + 1;
            bLastBlock = true;
        }

        rFunc(*it, nOffset, nDataSize);

        if (bLastBlock)
            break;
    }

    return it;
}

template<typename BlkT, typename ItrT, typename NodeT, typename FuncElem>
void EachElem(NodeT& rNode, size_t nOffset, size_t nDataSize, FuncElem& rFuncElem)
{
    ItrT it = BlkT::begin(*rNode.data);
    std::advance(it, nOffset);
    ItrT itEnd = it;
    std::advance(itEnd, nDataSize);
    size_t nRow = rNode.position + nOffset;
    for (; it != itEnd; ++it, ++nRow)
        rFuncElem(nRow, *it);
}

template<typename BlkT, typename ItrT, typename NodeT, typename FuncElem>
void EachElem(NodeT& rNode, FuncElem& rFuncElem)
{
    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);
}

template<typename BlkT, typename StoreT, typename FuncElem>
std::pair<typename StoreT::const_iterator, size_t>
CheckElem(
    const StoreT& rStore, const typename StoreT::const_iterator& it, size_t nOffset, size_t nDataSize,
    FuncElem& rFuncElem)
{
    typedef std::pair<typename StoreT::const_iterator, size_t> PositionType;

    typename BlkT::const_iterator itData = BlkT::begin(*it->data);
    std::advance(itData, nOffset);
    typename BlkT::const_iterator itDataEnd = itData;
    std::advance(itDataEnd, nDataSize);
    size_t nTopRow = it->position + nOffset;
    size_t nRow = nTopRow;
    for (; itData != itDataEnd; ++itData, ++nRow)
    {
        if (rFuncElem(nRow, *itData))
            return PositionType(it, nRow - it->position);
    }

    return PositionType(rStore.end(), 0);
}

template<typename StoreT, typename BlkT, typename FuncElem, typename FuncElse>
void ParseElements1(const StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse)
{
    typename StoreT::size_type nTopRow = 0, nDataSize = 0;
    typename StoreT::const_iterator it = rStore.begin(), itEnd = rStore.end();
    for (; it != itEnd; ++it, nTopRow += nDataSize)
    {
        nDataSize = it->size;
        if (it->type != BlkT::block_type)
        {
            rFuncElse(it->type, nTopRow, nDataSize);
            continue;
        }

        EachElem<BlkT, typename BlkT::const_iterator>(*it, rFuncElem);
    }
}

template<typename StoreT, typename BlkT, typename FuncElem, typename FuncElse>
typename StoreT::const_iterator
ParseElements1(
    const typename StoreT::const_iterator& itPos, const StoreT& rStore,
    typename StoreT::size_type nStart, typename StoreT::size_type nEnd,
    FuncElem& rFuncElem, FuncElse& rFuncElse)
{
    typedef std::pair<typename StoreT::const_iterator, typename StoreT::size_type> PositionType;

    PositionType aPos = rStore.position(itPos, nStart);
    typename StoreT::const_iterator it = aPos.first;
    typename StoreT::size_type nOffset = aPos.second;
    typename StoreT::size_type nDataSize = 0;
    typename StoreT::size_type nTopRow = nStart;

    for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
    {
        bool bLastBlock = false;
        nDataSize = it->size - nOffset;
        if (nTopRow + nDataSize - 1 > nEnd)
        {
            // Truncate the block.
            nDataSize = nEnd - nTopRow + 1;
            bLastBlock = true;
        }

        if (it->type == BlkT::block_type)
            EachElem<BlkT, typename BlkT::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
        else
            rFuncElse(it->type, nTopRow, nDataSize);

        if (bLastBlock)
            break;
    }

    return it;
};

template<typename StoreT, typename Blk1, typename Blk2, typename FuncElem, typename FuncElse>
typename StoreT::const_iterator
ParseElements2(
    const typename StoreT::const_iterator& itPos, const StoreT& rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd,
    FuncElem& rFuncElem, FuncElse& rFuncElse)
{
    typedef std::pair<typename StoreT::const_iterator, typename StoreT::size_type> PositionType;

    PositionType aPos = rStore.position(itPos, nStart);
    typename StoreT::const_iterator it = aPos.first;
    typename StoreT::size_type nOffset = aPos.second;
    typename StoreT::size_type nDataSize = 0;
    typename StoreT::size_type nTopRow = nStart;

    for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
    {
        bool bLastBlock = false;
        nDataSize = it->size - nOffset;
        if (nTopRow + nDataSize - 1 > nEnd)
        {
            // Truncate the block.
            nDataSize = nEnd - nTopRow + 1;
            bLastBlock = true;
        }

        switch (it->type)
        {
            case Blk1::block_type:
                EachElem<Blk1, typename Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
            break;
            case Blk2::block_type:
                EachElem<Blk2, typename Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
            break;
            default:
                rFuncElse(it->type, nTopRow, nDataSize);
        }

        if (bLastBlock)
            break;
    }

    return it;
}

template<typename StoreT, typename Blk1, typename Blk2, typename Blk3, typename Blk4, typename FuncElem, typename FuncElse>
typename StoreT::const_iterator
ParseElements4(
    const typename StoreT::const_iterator& itPos, const StoreT& rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd,
    FuncElem& rFuncElem, FuncElse& rFuncElse)
{
    typedef std::pair<typename StoreT::const_iterator, typename StoreT::size_type> PositionType;

    PositionType aPos = rStore.position(itPos, nStart);
    typename StoreT::const_iterator it = aPos.first;
    typename StoreT::size_type nOffset = aPos.second;
    typename StoreT::size_type nDataSize = 0;
    typename StoreT::size_type nTopRow = nStart;

    for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
    {
        bool bLastBlock = false;
        nDataSize = it->size - nOffset;
        if (nTopRow + nDataSize - 1 > nEnd)
        {
            // Truncate the block.
            nDataSize = nEnd - nTopRow + 1;
            bLastBlock = true;
        }

        switch (it->type)
        {
            case Blk1::block_type:
                EachElem<Blk1, typename Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
            break;
            case Blk2::block_type:
                EachElem<Blk2, typename Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
            break;
            case Blk3::block_type:
                EachElem<Blk3, typename Blk3::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
            break;
            case Blk4::block_type:
                EachElem<Blk4, typename Blk4::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
            break;
            default:
                rFuncElse(it->type, nTopRow, nDataSize);
        }

        if (bLastBlock)
            break;
    }

    return it;
}

template<typename StoreT, typename BlkT, typename FuncElem, typename FuncElse>
void ProcessElements1(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;
        if (it->type != BlkT::block_type)
        {
            rFuncElse(it->type, nTopRow, nDataSize);
            continue;
        }

        EachElem<BlkT, typename BlkT::iterator>(*it, rFuncElem);
    }
}

/**
 * This variant specifies start and end positions.
 */

template<typename StoreT, typename BlkT, typename FuncElem, typename FuncElse>
typename StoreT::iterator
ProcessElements1(
    const typename StoreT::iterator& itPos, StoreT& rStore,
    typename StoreT::size_type nStart, typename StoreT::size_type nEnd,
    FuncElem& rFuncElem, FuncElse& rFuncElse)
{
    typedef std::pair<typename StoreT::iterator, typename StoreT::size_type> PositionType;

    PositionType aPos = rStore.position(itPos, nStart);
    typename StoreT::iterator it = aPos.first;
    typename StoreT::size_type nOffset = aPos.second;
    typename StoreT::size_type nDataSize = 0;
    typename StoreT::size_type nTopRow = nStart;

    for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
    {
        bool bLastBlock = false;
        nDataSize = it->size - nOffset;
        if (nTopRow + nDataSize - 1 > nEnd)
        {
            // Truncate the block.
            nDataSize = nEnd - nTopRow + 1;
            bLastBlock = true;
        }

        if (it->type == BlkT::block_type)
            EachElem<BlkT, typename BlkT::iterator>(*it, nOffset, nDataSize, rFuncElem);
        else
            rFuncElse(it->type, nTopRow, nDataSize);

        if (bLastBlock)
            break;
    }

    return it;
};

template<typename StoreT, typename Blk1, typename Blk2, typename FuncElem, typename FuncElse>
void ProcessElements2(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:
                EachElem<Blk1, typename Blk1::iterator>(*it, rFuncElem);
            break;
            case Blk2::block_type:
                EachElem<Blk2, typename Blk2::iterator>(*it, rFuncElem);
            break;
            default:
                rFuncElse(it->type, nTopRow, nDataSize);
        }
    }
}

template<typename StoreT, typename Blk1, typename Blk2, typename FuncElem, typename FuncElse>
void ProcessElements2Reverse(StoreT& rStore, FuncElem& rFuncElem, FuncElse&&nbsp;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(
    const StoreT& rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd,
    FuncElem& rFuncElem, FuncElse& rFuncElse)
{
    typedef std::pair<typename StoreT::const_iterator, typename StoreT::size_type> PositionType;
    typedef std::pair<typename StoreT::size_type, bool> ElseRetType;

    PositionType aPos = rStore.position(nStart);
    typename StoreT::const_iterator it = aPos.first;
    typename StoreT::size_type nOffset = aPos.second;
    typename StoreT::size_type nDataSize = 0;
    typename StoreT::size_type nTopRow = nStart;

    for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
    {
        bool bLastBlock = false;
        nDataSize = it->size - nOffset;
        if (nTopRow + nDataSize - 1 > nEnd)
        {
            // Truncate the block.
            nDataSize = nEnd - nTopRow + 1;
            bLastBlock = true;
        }

        switch (it->type)
        {
            case Blk1::block_type:
            {
                PositionType aRet = CheckElem<Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
                if (aRet.first != rStore.end())
                    return aRet;
            }
            break;
            default:
            {
                ElseRetType aRet = rFuncElse(it->type, nTopRow, nDataSize);
                if (aRet.second)
                    return PositionType(it, aRet.first);
            }
        }

        if (bLastBlock)
            break;
    }

    return PositionType(rStore.end(), 0);
}

template<typename StoreT, typename Blk1, typename Blk2, typename FuncElem, typename FuncElse>
std::pair<typename StoreT::const_iterator, typename StoreT::size_type>
FindElement2(
    const StoreT& rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd,
    FuncElem& rFuncElem, FuncElse& rFuncElse)
{
    typedef std::pair<typename StoreT::const_iterator, typename StoreT::size_type> PositionType;
    typedef std::pair<typename StoreT::size_type, bool> ElseRetType;

    PositionType aPos = rStore.position(nStart);
    typename StoreT::const_iterator it = aPos.first;
    typename StoreT::size_type nOffset = aPos.second;
    typename StoreT::size_type nDataSize = 0;
    typename StoreT::size_type nTopRow = nStart;

    for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
    {
        bool bLastBlock = false;
        nDataSize = it->size - nOffset;
        if (nTopRow + nDataSize - 1 > nEnd)
        {
            // Truncate the block.
            nDataSize = nEnd - nTopRow + 1;
            bLastBlock = true;
        }

        switch (it->type)
        {
            case Blk1::block_type:
            {
                PositionType aRet = CheckElem<Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
                if (aRet.first != rStore.end())
                    return aRet;
            }
            break;
            case Blk2::block_type:
            {
                PositionType aRet = CheckElem<Blk2>(rStore, it, nOffset, nDataSize, rFuncElem);
                if (aRet.first != rStore.end())
                    return aRet;
            }
            break;
            default:
            {
                ElseRetType aRet = rFuncElse(*it, nOffset, nDataSize);
                if (aRet.second)
                    return PositionType(it, aRet.first);
            }
        }

        if (bLastBlock)
            break;
    }

    return PositionType(rStore.end(), 0);
}

// Efficiently set all elements for which the predicate returns true as empty.
template<typename Blk1, typename StoreT, typename FuncElem>
void SetElementsToEmpty1(
    StoreT& rStore, FuncElem& rFuncElem)
{
    typedef std::pair<typename StoreT::const_iterator, typename StoreT::size_type> PositionType;

    for (typename StoreT::iterator it = rStore.begin(); it != rStore.end(); ++it)
    {
        if (it->type == Blk1::block_type)
        {
            PositionType firstToEmpty = CheckElem<Blk1>(rStore, it, 0, it->size, rFuncElem);
            if (firstToEmpty.first != rStore.end())
            {
                typename StoreT::size_type nFirstOffset = firstToEmpty.second;
                typename StoreT::size_type nRemainingDataSize = it->size - nFirstOffset;
                FuncNotElem<FuncElem, typename Blk1::value_type> notFuncElem(rFuncElem);
                PositionType lastToEmpty = CheckElem<Blk1>(rStore, it, nFirstOffset, nRemainingDataSize,
                    notFuncElem);
                typename StoreT::size_type nLastOffset = lastToEmpty.first != rStore.end()
                    ? lastToEmpty.second - 1 : it->size - 1;
                it = rStore.set_empty(it, it->position + nFirstOffset, it->position + nLastOffset);
                // The returned iterator points to the empty elements block.
                assert(it->type == sc::element_type_empty);
            }
        }
    }
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5 in Prozent
C=98 H=92 G=94

¤ Dauer der Verarbeitung: 0.27 Sekunden  (vorverarbeitet am  2026-05-05) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.