Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/inc/ndindex.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
#ifndef INCLUDED_SW_INC_NDINDEX_HXX
20
#define INCLUDED_SW_INC_NDINDEX_HXX
21
22
#include <iostream>
23
24
#include "node.hxx"
25
#include "ring.hxx"
26
#include "ndarr.hxx"
27
#include "nodeoffset.hxx"
28
29
/// Marks a node in the document model.
30
class SAL_WARN_UNUSED SW_DLLPUBLIC SwNodeIndex final : public sw::Ring<SwNodeIndex>
31
{
32
    SwNode * m_pNode;
33
34
    void RegisterIndex()
35
304M
    {
36
304M
        if(!m_pNode->m_vIndices)
37
148M
        {
38
#if defined(__GNUC__) && (__GNUC__ == 12 || __GNUC__ == 13)
39
#pragma GCC diagnostic push
40
#pragma GCC diagnostic ignored "-Wdangling-pointer"
41
#endif
42
148M
            m_pNode->m_vIndices = this;
43
#if defined(__GNUC__) && (__GNUC__ == 12 || __GNUC__ == 13)
44
#pragma GCC diagnostic pop
45
#endif
46
148M
        }
47
304M
        MoveTo(m_pNode->m_vIndices);
48
304M
    }
49
    void DeRegisterIndex()
50
304M
    {
51
304M
        if(m_pNode->m_vIndices == this)
52
160M
            m_pNode->m_vIndices = GetNextInRing();
53
304M
        MoveTo(nullptr);
54
304M
        if(m_pNode->m_vIndices == this)
55
148M
            m_pNode->m_vIndices = nullptr;
56
304M
    }
57
58
246M
    SwNodeIndex(SwNode* pNode) : m_pNode(pNode) { RegisterIndex(); }
59
60
public:
61
0
    SwNodeIndex( const SwNodes& rNds, sal_Int32 nIdx ) : SwNodeIndex(rNds, SwNodeOffset(nIdx)) {}
62
    explicit SwNodeIndex( const SwNodes& rNds, SwNodeOffset nIdx = SwNodeOffset(0) )
63
17.0M
        : SwNodeIndex( rNds[ nIdx ] ) {}
64
65
7.67M
    SwNodeIndex( const SwNodeIndex& rIdx, sal_Int32 nDiff ) : SwNodeIndex(rIdx, SwNodeOffset(nDiff)) {}
66
    SwNodeIndex( const SwNodeIndex& rIdx, SwNodeOffset nDiff = SwNodeOffset(0) )
67
41.5M
        : SwNodeIndex( nDiff ? rIdx.GetNodes()[ rIdx.GetIndex() + nDiff ] : rIdx.m_pNode ) {}
68
69
155M
    SwNodeIndex( const SwNode& rNd, sal_Int32 nDiff ) : SwNodeIndex(rNd, SwNodeOffset(nDiff)) {}
70
    explicit SwNodeIndex( const SwNode& rNd )
71
187M
        : SwNodeIndex( const_cast<SwNode*>(&rNd) ) {}
72
    explicit SwNodeIndex( const SwNode& rNd, SwNodeOffset nDiff )
73
169M
        : SwNodeIndex( nDiff ? *rNd.GetNodes()[ rNd.GetIndex() + nDiff ] : rNd ) {}
74
75
246M
    virtual ~SwNodeIndex() override { DeRegisterIndex(); }
76
77
28.5M
    SwNodeIndex& operator++() { return operator+=(SwNodeOffset(1)); }
78
1.07M
    SwNodeIndex& operator--() { return operator-=(SwNodeOffset(1)); }
79
80
30.8M
    SwNodeIndex& operator+=( SwNodeOffset nOffset ) { return operator=(GetIndex() + nOffset); }
81
1.14M
    SwNodeIndex& operator-=( SwNodeOffset nOffset ) { return operator=(GetIndex() - nOffset); }
82
83
91.6M
    bool operator<( const SwNodeIndex& rIndex ) const { return operator<(rIndex.GetNode()); }
84
12.9M
    bool operator<=( const SwNodeIndex& rIndex ) const { return operator<=(rIndex.GetNode()); }
85
10.4M
    bool operator>( const SwNodeIndex& rIndex ) const { return operator>(rIndex.GetNode()); }
86
12.9M
    bool operator>=( const SwNodeIndex& rIndex ) const { return operator>=(rIndex.GetNode()); }
87
115M
    bool operator==( const SwNodeIndex& rIndex ) const { return operator==(rIndex.GetNode()); }
88
5.20M
    bool operator!=( const SwNodeIndex& rIndex ) const { return operator!=(rIndex.GetNode()); }
89
90
100M
    bool operator<( SwNodeOffset nOther ) const { return GetIndex() < nOther; }
91
25.1k
    bool operator<=( SwNodeOffset nOther ) const { return GetIndex() <= nOther; }
92
17.5M
    bool operator>( SwNodeOffset nOther ) const { return GetIndex() > nOther; }
93
182k
    bool operator>=( SwNodeOffset nOther ) const { return GetIndex() >= nOther; }
94
921
    bool operator==( SwNodeOffset nOther ) const { return GetIndex() == nOther; }
95
15.0k
    bool operator!=( SwNodeOffset nOther ) const { return GetIndex() != nOther; }
96
97
99.4M
    bool operator<( const SwNode& rNd ) const { assert(&GetNodes() == &rNd.GetNodes()); return operator<(rNd.GetIndex()); }
98
13.2M
    bool operator<=( const SwNode& rNd ) const { return operator==(rNd) || operator<(rNd); }
99
17.5M
    bool operator>( const SwNode& rNd ) const { assert(&GetNodes() == &rNd.GetNodes()); return operator>(rNd.GetIndex()); }
100
12.9M
    bool operator>=( const SwNode& rNd ) const { return operator==(rNd) || operator>(rNd); }
101
144M
    bool operator==( const SwNode& rNd ) const { return m_pNode == &rNd; }
102
5.21M
    bool operator!=( const SwNode& rNd ) const { return m_pNode != &rNd; }
103
104
    inline SwNodeIndex& operator=( SwNodeOffset );
105
11.1M
    SwNodeIndex& operator=( const SwNodeIndex& rIdx ) { return operator=(*rIdx.m_pNode); }
106
    inline SwNodeIndex& operator=( const SwNode& );
107
108
    // Return value of index as SwNodeOffset.
109
2.43G
    SwNodeOffset GetIndex() const { return m_pNode->GetIndex(); }
110
111
    // Enables assignments without creation of a temporary object.
112
0
    SwNodeIndex& Assign( SwNodes const & rNds, SwNodeOffset nIdx ) { return operator=(*rNds[nIdx]); }
113
1.81M
    SwNodeIndex& Assign( const SwNode& rNd, sal_Int32 nOffset ) { return Assign(rNd, SwNodeOffset(nOffset)); }
114
    inline SwNodeIndex& Assign( const SwNode& rNd, SwNodeOffset nOffset = SwNodeOffset(0) );
115
116
    // Gets pointer on NodesArray.
117
17.9M
    const SwNodes& GetNodes() const { return m_pNode->GetNodes(); }
118
74.6M
          SwNodes& GetNodes() { return m_pNode->GetNodes(); }
119
120
917M
    SwNode& GetNode() const { return *m_pNode; }
121
};
122
123
inline std::ostream &operator <<(std::ostream& s, const SwNodeIndex& index)
124
0
{
125
0
    return s << "SwNodeIndex (node " << sal_Int32(index.GetIndex()) << ")";
126
0
}
127
128
// SwRange
129
130
class SW_DLLPUBLIC SwNodeRange
131
{
132
public:
133
    SwNodeIndex aStart;
134
    SwNodeIndex aEnd;
135
136
    SwNodeRange( const SwNodeIndex &rS, const SwNodeIndex &rE )
137
19
        : aStart( rS ), aEnd( rE ) {}
138
    SwNodeRange( const SwNode &rS, const SwNode &rE )
139
111k
        : aStart( rS ), aEnd( rE ) {}
140
191k
    SwNodeRange( const SwNodeRange &rRange ) = default;
141
142
    SwNodeRange( const SwNodes& rNds, SwNodeOffset nSttIdx, SwNodeOffset nEndIdx = SwNodeOffset(0) )
143
0
        : aStart( rNds, nSttIdx ), aEnd( rNds, nEndIdx ) {}
144
145
    SwNodeRange( const SwNodeIndex& rS, SwNodeOffset nSttDiff, const SwNodeIndex& rE, SwNodeOffset nEndDiff = SwNodeOffset(0) )
146
9.79k
        : aStart( rS, nSttDiff ), aEnd( rE, nEndDiff ) {}
147
    SwNodeRange( const SwNode& rS, SwNodeOffset nSttDiff, const SwNode& rE, SwNodeOffset nEndDiff = SwNodeOffset(0) )
148
445k
        : aStart( rS, nSttDiff ), aEnd( rE, nEndDiff ) {}
149
};
150
151
// For inlines node.hxx is needed which in turn needs this one.
152
// Therefore all inlines accessing m_pNode are implemented here.
153
154
inline SwNodeIndex& SwNodeIndex::operator=( SwNodeOffset const nNew )
155
37.6M
{
156
37.6M
    auto pNewNode = GetNodes()[ nNew ];
157
37.6M
    if (pNewNode != m_pNode)
158
35.4M
    {
159
35.4M
        DeRegisterIndex();
160
35.4M
        m_pNode = GetNodes()[ nNew ];
161
35.4M
        RegisterIndex();
162
35.4M
    }
163
37.6M
    return *this;
164
37.6M
}
165
166
SwNodeIndex& SwNodeIndex::operator=( const SwNode& rNd )
167
27.3M
{
168
27.3M
    if (&rNd != m_pNode)
169
22.3M
    {
170
22.3M
        DeRegisterIndex();
171
22.3M
        m_pNode = const_cast<SwNode*>(&rNd);
172
22.3M
        RegisterIndex();
173
22.3M
    }
174
27.3M
    return *this;
175
27.3M
}
176
177
SwNodeIndex& SwNodeIndex::Assign( const SwNode& rNd, SwNodeOffset nOffset )
178
4.36M
{
179
4.36M
    const SwNode* pNewNode;
180
4.36M
    if (nOffset)
181
1.94M
        pNewNode = rNd.GetNodes()[ rNd.GetIndex() + nOffset ];
182
2.42M
    else
183
2.42M
        pNewNode = &rNd;
184
4.36M
    return operator=(*pNewNode);
185
4.36M
}
186
187
#endif
188
189
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */