LCOV - code coverage report
Current view: top level - src/engraving/infrastructure - ld_access.h Coverage Total Hit
Test: filtered_coverage.info Lines: 100.0 % 20 20
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) 2023 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              : #ifndef MU_ENGRAVING_LD_ACCESS_DEV_H
      23              : #define MU_ENGRAVING_LD_ACCESS_DEV_H
      24              : 
      25              : #include <optional>
      26              : 
      27              : #include "log.h"
      28              : 
      29              : namespace mu::engraving {
      30              : //! NOTE Enum for detect layoutdata bad access errors
      31              : enum class LD_ACCESS : unsigned char {
      32              :     CHECK = 0,          // should be correct; assert if still not
      33              :     BAD,                // known to be bad; don’t assert, we’ll fix it later
      34              :     MAYBE_NOTINITED,    // in this case it’s okay if we access it before it’s been inited
      35              :     PASS                // for debug
      36              : };
      37              : 
      38              : #ifdef MUE_ENABLE_ENGRAVING_LD_ACCESS
      39              : 
      40              : //! TODO Using this macro, we can collect and output debugging information to show the dependency tree
      41              : #define LD_CONDITION(val) \
      42              :     if (!val) { \
      43              :         LOGE_T("LD_ACCESS")() << "BAD ACCESS to: " << #val << ", file: " << __FILE__ << ", line: " << __LINE__; \
      44              :     } \
      45              : 
      46              : #else
      47              : #define LD_CONDITION(val) (void)val;
      48              : #endif
      49              : 
      50              : // mark as independent
      51              : #define LD_INDEPENDENT
      52              : 
      53              : template<typename T>
      54              : class ld_field_debug
      55              : {
      56              : public:
      57              : 
      58      2232171 :     ld_field_debug(const char* name, T def = T())
      59      2232171 :         : m_name(name), m_def(def) {}
      60              : 
      61      1194783 :     inline void reset() { m_val.reset(); }
      62              : 
      63      1127368 :     inline bool has_value() const { return m_val.has_value(); }
      64              : 
      65     24055637 :     inline const T& value(LD_ACCESS mode = LD_ACCESS::CHECK) const
      66              :     {
      67     24055637 :         if (!m_val.has_value()) {
      68              : #ifdef MUE_ENABLE_ENGRAVING_LD_ACCESS
      69              :             if (mode == LD_ACCESS::CHECK) {
      70              :                 LOGE_T("LD_ACCESS")() << "BAD ACCESS to: " << m_name;
      71              :             }
      72              : #else
      73              :             UNUSED(mode);
      74              : #endif
      75      1999989 :             return m_def;
      76              :         }
      77     22055648 :         return m_val.value();
      78              :     }
      79              : 
      80       511818 :     inline const T& operator()() const
      81              :     {
      82       511818 :         return value();
      83              :     }
      84              : 
      85      5416384 :     operator T() const {
      86      5416384 :         return value();
      87              :     }
      88              : 
      89      5175913 :     inline T& mut_value()
      90              :     {
      91      5175913 :         if (!m_val.has_value()) {
      92       546832 :             m_val = std::make_optional<T>(m_def);
      93              :         }
      94      5175913 :         return m_val.value();
      95              :     }
      96              : 
      97      3039853 :     inline void set_value(const T& v)
      98              :     {
      99      3039853 :         m_val = std::make_optional<T>(v);
     100      3039853 :     }
     101              : 
     102       328860 :     ld_field_debug& operator=(const T& v) { m_val = v; return *this; }
     103              : 
     104              : private:
     105              :     const char* m_name = nullptr;
     106              :     T m_def;
     107              :     std::optional<T> m_val;
     108              : };
     109              : 
     110              : template<typename T>
     111              : class ld_field_prod
     112              : {
     113              : public:
     114              : 
     115              :     ld_field_prod(const char*, T def = T())
     116              :         : m_val(def) {}
     117              : 
     118              :     inline void reset() { m_val = T(); }
     119              : 
     120              :     inline bool has_value() const { return true; }
     121              : 
     122              :     inline const T& value(LD_ACCESS = LD_ACCESS::CHECK) const
     123              :     {
     124              :         return m_val;
     125              :     }
     126              : 
     127              :     inline const T& operator()() const
     128              :     {
     129              :         return value();
     130              :     }
     131              : 
     132              :     operator T() const {
     133              :         return value();
     134              :     }
     135              : 
     136              :     inline T& mut_value()
     137              :     {
     138              :         return m_val;
     139              :     }
     140              : 
     141              :     inline void set_value(const T& v)
     142              :     {
     143              :         m_val = v;
     144              :     }
     145              : 
     146              :     ld_field_prod& operator=(const T& v) { m_val = v; return *this; }
     147              : 
     148              : private:
     149              :     T m_val;
     150              : };
     151              : 
     152              : #ifdef NDEBUG
     153              : template<typename T>
     154              : using ld_field = ld_field_prod<T>;
     155              : #else
     156              : template<typename T>
     157              : using ld_field = ld_field_debug<T>;
     158              : #endif
     159              : }
     160              : 
     161              : #endif // MU_ENGRAVING_LD_ACCESS_DEV_H
        

Generated by: LCOV version 2.0-1