LCOV - code coverage report
Current view: top level - src/engraving/dom - segmentlist.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 77.3 % 128 99
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2021 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : 
      23              : #include "segmentlist.h"
      24              : #include "segment.h"
      25              : #include "score.h"
      26              : 
      27              : #include "log.h"
      28              : 
      29              : using namespace mu;
      30              : 
      31              : namespace mu::engraving {
      32              : //---------------------------------------------------------
      33              : //   clone
      34              : //---------------------------------------------------------
      35              : 
      36            0 : SegmentList SegmentList::clone() const
      37              : {
      38            0 :     SegmentList dl;
      39            0 :     Segment* s = m_first;
      40            0 :     for (int i = 0; i < m_size; ++i) {
      41            0 :         Segment* ns = s->clone();
      42            0 :         dl.push_back(ns);
      43            0 :         s = s->next();
      44              :     }
      45            0 :     dl.check();
      46            0 :     return dl;
      47              : }
      48              : 
      49            0 : Segment* SegmentList::at(int index) const
      50              : {
      51            0 :     Segment* s = m_first;
      52            0 :     for (int i = 0; i < m_size; ++i) {
      53            0 :         if (i == index) {
      54            0 :             return s;
      55              :         }
      56            0 :         s = s->next();
      57              :     }
      58            0 :     return nullptr;
      59              : }
      60              : 
      61        30515 : Segment* SegmentList::firstActive() const
      62              : {
      63        30515 :     if (Segment* segment = m_first) {
      64        30515 :         return segment->isActive() ? segment : segment->nextActive();
      65              :     }
      66            0 :     return nullptr;
      67              : }
      68              : 
      69              : //---------------------------------------------------------
      70              : //   check
      71              : //---------------------------------------------------------
      72              : 
      73              : #ifndef NDEBUG
      74       161786 : void SegmentList::check()
      75              : {
      76       161786 :     int n = 0;
      77       161786 :     Segment* f = 0;
      78       161786 :     Segment* l = 0;
      79       814127 :     for (Segment* s = m_first; s; s = s->next()) {
      80       652341 :         if (f == 0) {
      81       161786 :             f = s;
      82              :         }
      83       652341 :         l = s;
      84       652341 :         ++n;
      85              :     }
      86       814127 :     for (Segment* s = m_first; s; s = s->next()) {
      87       652341 :         switch (s->segmentType()) {
      88       652341 :         case SegmentType::Invalid:
      89              :         case SegmentType::BeginBarLine:
      90              :         case SegmentType::HeaderClef:
      91              :         case SegmentType::Clef:
      92              :         case SegmentType::KeySig:
      93              :         case SegmentType::Ambitus:
      94              :         case SegmentType::TimeSig:
      95              :         case SegmentType::StartRepeatBarLine:
      96              :         case SegmentType::BarLine:
      97              :         case SegmentType::ChordRest:
      98              :         case SegmentType::Breath:
      99              :         case SegmentType::ClefRepeatAnnounce:
     100              :         case SegmentType::TimeSigRepeatAnnounce:
     101              :         case SegmentType::KeySigRepeatAnnounce:
     102              :         case SegmentType::ClefStartRepeatAnnounce:
     103              :         case SegmentType::TimeSigStartRepeatAnnounce:
     104              :         case SegmentType::KeySigStartRepeatAnnounce:
     105              :         case SegmentType::EndBarLine:
     106              :         case SegmentType::TimeSigAnnounce:
     107              :         case SegmentType::KeySigAnnounce:
     108              :         case SegmentType::TimeTick:
     109       652341 :             break;
     110            0 :         default:
     111            0 :             ASSERT_X(String(u"SegmentList::check: invalid segment type: %1").arg(int(s->segmentType())));
     112              :             break;
     113              :         }
     114       652341 :         Segment* ss = s->next();
     115      2622346 :         while (ss) {
     116      1970005 :             if (s == ss) {
     117            0 :                 ASSERT_X("SegmentList::check: segment twice in list");
     118              :             }
     119      1970005 :             ss = ss->next();
     120              :         }
     121              :     }
     122       161786 :     if (f != m_first) {
     123            0 :         ASSERT_X("SegmentList::check: bad first");
     124              :     }
     125       161786 :     if (l != m_last) {
     126            0 :         ASSERT_X("SegmentList::check: bad last");
     127              :     }
     128       161786 :     if (f && f->prev()) {
     129            0 :         ASSERT_X("SegmentList::check: first has prev");
     130              :     }
     131       161786 :     if (l && l->next()) {
     132            0 :         ASSERT_X("SegmentList::check: last has next");
     133              :     }
     134       161786 :     if (n != m_size) {
     135            0 :         ASSERT_X(String(u"SegmentList::check: counted %1 but _size is %d2").arg(n, m_size));
     136              :         m_size = n;
     137              :     }
     138       161786 : }
     139              : 
     140              : #endif
     141              : 
     142              : //---------------------------------------------------------
     143              : //   insert
     144              : ///   Insert Segment \a e before Segment \a el.
     145              : //---------------------------------------------------------
     146              : 
     147        81092 : void SegmentList::insert(Segment* e, Segment* el)
     148              : {
     149        81092 :     if (el == 0) {
     150        56079 :         push_back(e);
     151        25013 :     } else if (el == first()) {
     152        10183 :         push_front(e);
     153              :     } else {
     154        14830 :         ++m_size;
     155        14830 :         e->setNext(el);
     156        14830 :         e->setPrev(el->prev());
     157        14830 :         el->prev()->setNext(e);
     158        14830 :         el->setPrev(e);
     159              :     }
     160        81092 :     check();
     161        81092 : }
     162              : 
     163              : //---------------------------------------------------------
     164              : //   remove
     165              : //---------------------------------------------------------
     166              : 
     167        14432 : void SegmentList::remove(Segment* e)
     168              : {
     169              : #ifndef NDEBUG
     170        14432 :     check();
     171        14432 :     bool found = false;
     172        21943 :     for (Segment* s = m_first; s; s = s->next()) {
     173        21943 :         if (e == s) {
     174        14432 :             found = true;
     175        14432 :             break;
     176              :         }
     177              :     }
     178        14432 :     if (!found) {
     179            0 :         ASSERT_X(String(u"segment %1 not in list").arg(String::fromAscii(e->subTypeName())));
     180              :     }
     181              : #endif
     182        14432 :     --m_size;
     183        14432 :     if (e == m_first) {
     184        12325 :         m_first = m_first->next();
     185        12325 :         if (m_first) {
     186        12292 :             m_first->setPrev(0);
     187              :         }
     188        12325 :         if (e == m_last) {
     189           33 :             m_last = 0;
     190              :         }
     191         2107 :     } else if (e == m_last) {
     192           97 :         m_last = m_last->prev();
     193           97 :         if (m_last) {
     194           97 :             m_last->setNext(0);
     195              :         }
     196              :     } else {
     197         2010 :         e->prev()->setNext(e->next());
     198         2010 :         e->next()->setPrev(e->prev());
     199              :     }
     200        14432 : }
     201              : 
     202              : //---------------------------------------------------------
     203              : //   push_back
     204              : //---------------------------------------------------------
     205              : 
     206        56079 : void SegmentList::push_back(Segment* e)
     207              : {
     208        56079 :     ++m_size;
     209        56079 :     e->setNext(0);
     210        56079 :     if (m_last) {
     211        38890 :         m_last->setNext(e);
     212              :     } else {
     213        17189 :         m_first = e;
     214              :     }
     215        56079 :     e->setPrev(m_last);
     216        56079 :     m_last = e;
     217        56079 :     check();
     218        56079 : }
     219              : 
     220              : //---------------------------------------------------------
     221              : //   push_front
     222              : //---------------------------------------------------------
     223              : 
     224        10183 : void SegmentList::push_front(Segment* e)
     225              : {
     226        10183 :     ++m_size;
     227        10183 :     e->setPrev(0);
     228        10183 :     if (m_first) {
     229        10183 :         m_first->setPrev(e);
     230              :     } else {
     231            0 :         m_last = e;
     232              :     }
     233        10183 :     e->setNext(m_first);
     234        10183 :     m_first = e;
     235        10183 :     check();
     236        10183 : }
     237              : 
     238              : //---------------------------------------------------------
     239              : //   firstCRSegment
     240              : //---------------------------------------------------------
     241              : 
     242        10355 : Segment* SegmentList::firstCRSegment() const
     243              : {
     244        10355 :     return first(SegmentType::ChordRest);
     245              : }
     246              : 
     247              : //---------------------------------------------------------
     248              : //   first
     249              : //---------------------------------------------------------
     250              : 
     251       834439 : Segment* SegmentList::first(SegmentType types) const
     252              : {
     253      1430404 :     for (Segment* s = m_first; s; s = s->next()) {
     254      1398968 :         if (s->segmentType() & types) {
     255       803003 :             return s;
     256              :         }
     257              :     }
     258        31436 :     return 0;
     259              : }
     260              : 
     261              : //---------------------------------------------------------
     262              : //   first
     263              : //---------------------------------------------------------
     264              : 
     265       131313 : Segment* SegmentList::first(ElementFlag flags) const
     266              : {
     267       134467 :     for (Segment* s = m_first; s; s = s->next()) {
     268       134467 :         if (s->flag(flags)) {
     269       131313 :             return s;
     270              :         }
     271              :     }
     272            0 :     return nullptr;
     273              : }
     274              : 
     275              : //---------------------------------------------------------
     276              : //   last
     277              : //---------------------------------------------------------
     278              : 
     279         4893 : Segment* SegmentList::last(ElementFlag flags) const
     280              : {
     281         4894 :     for (Segment* s = m_last; s; s = s->prev()) {
     282         4894 :         if (s->flag(flags)) {
     283         4893 :             return s;
     284              :         }
     285              :     }
     286            0 :     return nullptr;
     287              : }
     288              : 
     289         1136 : Segment* SegmentList::last(SegmentType types) const
     290              : {
     291         1649 :     for (Segment* s = m_last; s; s = s->prev()) {
     292         1621 :         if (s->segmentType() & types) {
     293         1108 :             return s;
     294              :         }
     295              :     }
     296           28 :     return nullptr;
     297              : }
     298              : }
        

Generated by: LCOV version 2.0-1