Coverage Report

Created: 2026-02-10 07:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/text/qfragmentmap_p.h
Line
Count
Source
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
#ifndef QFRAGMENTMAP_P_H
5
#define QFRAGMENTMAP_P_H
6
7
//
8
//  W A R N I N G
9
//  -------------
10
//
11
// This file is not part of the Qt API.  It exists purely as an
12
// implementation detail.  This header file may change from version to
13
// version without notice, or even be removed.
14
//
15
// We mean it.
16
//
17
18
#include <QtGui/private/qtguiglobal_p.h>
19
#include <stdlib.h>
20
#include <private/qtools_p.h>
21
22
QT_BEGIN_NAMESPACE
23
24
25
template <int N = 1>
26
class QFragment
27
{
28
public:
29
    quint32 parent;
30
    quint32 left;
31
    quint32 right;
32
    quint32 color;
33
    quint32 size_left_array[N];
34
    quint32 size_array[N];
35
    enum {size_array_max = N };
36
};
37
38
template <class Fragment>
39
class QFragmentMapData
40
{
41
    enum Color { Red, Black };
42
public:
43
    QFragmentMapData();
44
    ~QFragmentMapData();
45
46
    void init();
47
48
    class Header
49
    {
50
    public:
51
        quint32 root; // this relies on being at the same position as parent in the fragment struct
52
        quint32 tag;
53
        quint32 freelist;
54
        quint32 node_count;
55
        quint32 allocated;
56
    };
57
58
59
    enum {fragmentSize = sizeof(Fragment) };
60
61
62
    int length(uint field = 0) const;
63
64
65
0
    inline Fragment *fragment(uint index) {
66
0
        return (fragments + index);
67
0
    }
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::fragment(unsigned int)
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::fragment(unsigned int)
68
0
    inline const Fragment *fragment(uint index) const {
69
0
        return (fragments + index);
70
0
    }
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::fragment(unsigned int) const
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::fragment(unsigned int) const
71
72
73
0
    inline Fragment &F(uint index) { return fragments[index] ; }
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::F(unsigned int)
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::F(unsigned int)
74
0
    inline const Fragment &F(uint index) const { return fragments[index] ; }
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::F(unsigned int) const
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::F(unsigned int) const
75
76
    inline bool isRoot(uint index) const {
77
        return !fragment(index)->parent;
78
    }
79
80
0
    inline uint position(uint node, uint field = 0) const {
81
0
        Q_ASSERT(field < Fragment::size_array_max);
82
0
        const Fragment *f = fragment(node);
83
0
        uint offset = f->size_left_array[field];
84
0
        while (f->parent) {
85
0
            uint p = f->parent;
86
0
            f = fragment(p);
87
0
            if (f->right == node)
88
0
                offset += f->size_left_array[field] + f->size_array[field];
89
0
            node = p;
90
0
        }
91
0
        return offset;
92
0
    }
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::position(unsigned int, unsigned int) const
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::position(unsigned int, unsigned int) const
93
0
    inline uint sizeRight(uint node, uint field = 0) const {
94
0
        Q_ASSERT(field < Fragment::size_array_max);
95
0
        uint sr = 0;
96
0
        const Fragment *f = fragment(node);
97
0
        node = f->right;
98
0
        while (node) {
99
0
            f = fragment(node);
100
0
            sr += f->size_left_array[field] + f->size_array[field];
101
0
            node = f->right;
102
0
        }
103
0
        return sr;
104
0
    }
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::sizeRight(unsigned int, unsigned int) const
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::sizeRight(unsigned int, unsigned int) const
105
0
    inline uint sizeLeft(uint node, uint field = 0) const {
106
0
        Q_ASSERT(field < Fragment::size_array_max);
107
0
        return fragment(node)->size_left_array[field];
108
0
    }
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::sizeLeft(unsigned int, unsigned int) const
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::sizeLeft(unsigned int, unsigned int) const
109
110
111
0
    inline uint size(uint node, uint field = 0) const {
112
0
        Q_ASSERT(field < Fragment::size_array_max);
113
0
        return fragment(node)->size_array[field];
114
0
    }
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::size(unsigned int, unsigned int) const
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::size(unsigned int, unsigned int) const
115
116
0
    inline void setSize(uint node, int new_size, uint field = 0) {
117
0
        Q_ASSERT(field < Fragment::size_array_max);
118
0
        Fragment *f = fragment(node);
119
0
        int diff = new_size - f->size_array[field];
120
0
        f->size_array[field] = new_size;
121
0
        while (f->parent) {
122
0
            uint p = f->parent;
123
0
            f = fragment(p);
124
0
            if (f->left == node)
125
0
                f->size_left_array[field] += diff;
126
0
            node = p;
127
0
        }
128
0
    }
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::setSize(unsigned int, int, unsigned int)
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::setSize(unsigned int, int, unsigned int)
129
130
131
    uint findNode(int k, uint field = 0) const;
132
133
    uint insert_single(int key, uint length);
134
    uint erase_single(uint f);
135
136
0
    uint minimum(uint n) const {
137
0
        while (n && fragment(n)->left)
138
0
            n = fragment(n)->left;
139
0
        return n;
140
0
    }
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::minimum(unsigned int) const
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::minimum(unsigned int) const
141
142
0
    uint maximum(uint n) const {
143
0
        while (n && fragment(n)->right)
144
0
            n = fragment(n)->right;
145
0
        return n;
146
0
    }
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::maximum(unsigned int) const
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::maximum(unsigned int) const
147
148
    uint next(uint n) const;
149
    uint previous(uint n) const;
150
151
0
    inline uint root() const {
152
0
        Q_ASSERT(!head->root || !fragment(head->root)->parent);
153
0
        return head->root;
154
0
    }
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::root() const
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::root() const
155
    inline void setRoot(uint new_root) {
156
        Q_ASSERT(!head->root || !fragment(new_root)->parent);
157
        head->root = new_root;
158
    }
159
160
0
    inline bool isValid(uint n) const {
161
0
        return n > 0 && n != head->freelist;
162
0
    }
163
164
    union {
165
        Header *head;
166
        Fragment *fragments;
167
    };
168
169
private:
170
171
    void rotateLeft(uint x);
172
    void rotateRight(uint x);
173
    void rebalance(uint x);
174
    void removeAndRebalance(uint z);
175
176
    uint createFragment();
177
    void freeFragment(uint f);
178
179
};
180
181
template <class Fragment>
182
QFragmentMapData<Fragment>::QFragmentMapData()
183
0
    : fragments(nullptr)
184
0
{
185
0
    init();
186
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::QFragmentMapData()
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::QFragmentMapData()
187
188
template <class Fragment>
189
void QFragmentMapData<Fragment>::init()
190
0
{
191
    // the following code will realloc an existing fragment or create a new one.
192
    // it will also ignore errors when shrinking an existing fragment.
193
0
    Fragment *newFragments = (Fragment *)realloc(fragments, 64*fragmentSize);
194
0
    if (newFragments) {
195
0
        fragments = newFragments;
196
0
        head->allocated = 64;
197
0
    }
198
0
    Q_CHECK_PTR(fragments);
199
200
0
    head->tag = (((quint32)'p') << 24) | (((quint32)'m') << 16) | (((quint32)'a') << 8) | 'p'; //TAG('p', 'm', 'a', 'p');
201
0
    head->root = 0;
202
0
    head->freelist = 1;
203
0
    head->node_count = 0;
204
    // mark all items to the right as unused
205
0
    F(head->freelist).right = 0;
206
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::init()
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::init()
207
208
template <class Fragment>
209
QFragmentMapData<Fragment>::~QFragmentMapData()
210
0
{
211
0
    free(fragments);
212
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::~QFragmentMapData()
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::~QFragmentMapData()
213
214
template <class Fragment>
215
uint QFragmentMapData<Fragment>::createFragment()
216
0
{
217
0
    Q_ASSERT(head->freelist <= head->allocated);
218
219
0
    uint freePos = head->freelist;
220
0
    if (freePos == head->allocated) {
221
        // need to create some free space
222
0
        auto blockInfo = qCalculateGrowingBlockSize(freePos + 1, fragmentSize);
223
0
        Fragment *newFragments = (Fragment *)realloc(fragments, blockInfo.size);
224
0
        Q_CHECK_PTR(newFragments);
225
0
        fragments = newFragments;
226
0
        head->allocated = quint32(blockInfo.elementCount);
227
0
        F(freePos).right = 0;
228
0
    }
229
230
0
    uint nextPos = F(freePos).right;
231
0
    if (!nextPos) {
232
0
        nextPos = freePos+1;
233
0
        if (nextPos < head->allocated)
234
0
            F(nextPos).right = 0;
235
0
    }
236
237
0
    head->freelist = nextPos;
238
239
0
    ++head->node_count;
240
241
0
    return freePos;
242
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::createFragment()
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::createFragment()
243
244
template <class Fragment>
245
void QFragmentMapData<Fragment>::freeFragment(uint i)
246
0
{
247
0
    F(i).right = head->freelist;
248
0
    head->freelist = i;
249
250
0
    --head->node_count;
251
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::freeFragment(unsigned int)
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::freeFragment(unsigned int)
252
253
254
template <class Fragment>
255
0
uint QFragmentMapData<Fragment>::next(uint n) const {
256
0
    Q_ASSERT(n);
257
0
    if (F(n).right) {
258
0
        n = F(n).right;
259
0
        while (F(n).left)
260
0
            n = F(n).left;
261
0
    } else {
262
0
        uint y = F(n).parent;
263
0
        while (F(n).parent && n == F(y).right) {
264
0
            n = y;
265
0
            y = F(y).parent;
266
0
        }
267
0
        n = y;
268
0
    }
269
0
    return n;
270
0
}
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::next(unsigned int) const
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::next(unsigned int) const
271
272
template <class Fragment>
273
0
uint QFragmentMapData<Fragment>::previous(uint n) const {
274
0
    if (!n)
275
0
        return maximum(root());
276
277
0
    if (F(n).left) {
278
0
        n = F(n).left;
279
0
        while (F(n).right)
280
0
            n = F(n).right;
281
0
    } else {
282
0
        uint y = F(n).parent;
283
0
        while (F(n).parent && n == F(y).left) {
284
0
            n = y;
285
0
            y = F(y).parent;
286
0
        }
287
0
        n = y;
288
0
    }
289
0
    return n;
290
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::previous(unsigned int) const
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::previous(unsigned int) const
291
292
293
/*
294
     x              y
295
      \            / \
296
       y    -->   x   b
297
      / \          \
298
     a   b          a
299
*/
300
template <class Fragment>
301
void QFragmentMapData<Fragment>::rotateLeft(uint x)
302
0
{
303
0
    uint p = F(x).parent;
304
0
    uint y = F(x).right;
305
306
307
0
    if (y) {
308
0
        F(x).right = F(y).left;
309
0
        if (F(y).left)
310
0
            F(F(y).left).parent = x;
311
0
        F(y).left = x;
312
0
        F(y).parent = p;
313
0
    } else {
314
0
        F(x).right = 0;
315
0
    }
316
0
    if (!p) {
317
0
        Q_ASSERT(head->root == x);
318
0
        head->root = y;
319
0
    }
320
0
    else if (x == F(p).left)
321
0
        F(p).left = y;
322
0
    else
323
0
        F(p).right = y;
324
0
    F(x).parent = y;
325
0
    for (uint field = 0; field < Fragment::size_array_max; ++field)
326
0
        F(y).size_left_array[field] += F(x).size_left_array[field] + F(x).size_array[field];
327
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::rotateLeft(unsigned int)
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::rotateLeft(unsigned int)
328
329
330
/*
331
         x          y
332
        /          / \
333
       y    -->   a   x
334
      / \            /
335
     a   b          b
336
*/
337
template <class Fragment>
338
void QFragmentMapData<Fragment>::rotateRight(uint x)
339
0
{
340
0
    uint y = F(x).left;
341
0
    uint p = F(x).parent;
342
343
0
    if (y) {
344
0
        F(x).left = F(y).right;
345
0
        if (F(y).right)
346
0
            F(F(y).right).parent = x;
347
0
        F(y).right = x;
348
0
        F(y).parent = p;
349
0
    } else {
350
0
        F(x).left = 0;
351
0
    }
352
0
    if (!p) {
353
0
        Q_ASSERT(head->root == x);
354
0
        head->root = y;
355
0
    }
356
0
    else if (x == F(p).right)
357
0
        F(p).right = y;
358
0
    else
359
0
        F(p).left = y;
360
0
    F(x).parent = y;
361
0
    for (uint field = 0; field < Fragment::size_array_max; ++field)
362
0
        F(x).size_left_array[field] -= F(y).size_left_array[field] + F(y).size_array[field];
363
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::rotateRight(unsigned int)
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::rotateRight(unsigned int)
364
365
366
template <class Fragment>
367
void QFragmentMapData<Fragment>::rebalance(uint x)
368
0
{
369
0
    F(x).color = Red;
370
371
0
    while (F(x).parent && F(F(x).parent).color == Red) {
372
0
        uint p = F(x).parent;
373
0
        uint pp = F(p).parent;
374
0
        Q_ASSERT(pp);
375
0
        if (p == F(pp).left) {
376
0
            uint y = F(pp).right;
377
0
            if (y && F(y).color == Red) {
378
0
                F(p).color = Black;
379
0
                F(y).color = Black;
380
0
                F(pp).color = Red;
381
0
                x = pp;
382
0
            } else {
383
0
                if (x == F(p).right) {
384
0
                    x = p;
385
0
                    rotateLeft(x);
386
0
                    p = F(x).parent;
387
0
                    pp = F(p).parent;
388
0
                }
389
0
                F(p).color = Black;
390
0
                if (pp) {
391
0
                    F(pp).color = Red;
392
0
                    rotateRight(pp);
393
0
                }
394
0
            }
395
0
        } else {
396
0
            uint y = F(pp).left;
397
0
            if (y && F(y).color == Red) {
398
0
                F(p).color = Black;
399
0
                F(y).color = Black;
400
0
                F(pp).color = Red;
401
0
                x = pp;
402
0
            } else {
403
0
                if (x == F(p).left) {
404
0
                    x = p;
405
0
                    rotateRight(x);
406
0
                    p = F(x).parent;
407
0
                    pp = F(p).parent;
408
0
                }
409
0
                F(p).color = Black;
410
0
                if (pp) {
411
0
                    F(pp).color = Red;
412
0
                    rotateLeft(pp);
413
0
                }
414
0
            }
415
0
        }
416
0
    }
417
0
    F(root()).color = Black;
418
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::rebalance(unsigned int)
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::rebalance(unsigned int)
419
420
421
template <class Fragment>
422
uint QFragmentMapData<Fragment>::erase_single(uint z)
423
0
{
424
0
    uint w = previous(z);
425
0
    uint y = z;
426
0
    uint x;
427
0
    uint p;
428
429
0
    if (!F(y).left) {
430
0
        x = F(y).right;
431
0
    } else if (!F(y).right) {
432
0
        x = F(y).left;
433
0
    } else {
434
0
        y = F(y).right;
435
0
        while (F(y).left)
436
0
            y = F(y).left;
437
0
        x = F(y).right;
438
0
    }
439
440
0
    if (y != z) {
441
0
        F(F(z).left).parent = y;
442
0
        F(y).left = F(z).left;
443
0
        for (uint field = 0; field < Fragment::size_array_max; ++field)
444
0
            F(y).size_left_array[field] = F(z).size_left_array[field];
445
0
        if (y != F(z).right) {
446
            /*
447
                     z                y
448
                    / \              / \
449
                   a   b            a   b
450
                      /                /
451
                    ...     -->      ...
452
                    /                /
453
                   y                x
454
                  / \
455
                 0   x
456
             */
457
0
            p = F(y).parent;
458
0
            if (x)
459
0
                F(x).parent = p;
460
0
            F(p).left = x;
461
0
            F(y).right = F(z).right;
462
0
            F(F(z).right).parent = y;
463
0
            uint n = p;
464
0
            while (n != y) {
465
0
                for (uint field = 0; field < Fragment::size_array_max; ++field)
466
0
                    F(n).size_left_array[field] -= F(y).size_array[field];
467
0
                n = F(n).parent;
468
0
            }
469
0
        } else {
470
            /*
471
                     z                y
472
                    / \              / \
473
                   a   y     -->    a   x
474
                      / \
475
                     0   x
476
             */
477
0
            p = y;
478
0
        }
479
0
        uint zp = F(z).parent;
480
0
        if (!zp) {
481
0
            Q_ASSERT(head->root == z);
482
0
            head->root = y;
483
0
        } else if (F(zp).left == z) {
484
0
            F(zp).left = y;
485
0
            for (uint field = 0; field < Fragment::size_array_max; ++field)
486
0
                F(zp).size_left_array[field] -= F(z).size_array[field];
487
0
        } else {
488
0
            F(zp).right = y;
489
0
        }
490
0
        F(y).parent = zp;
491
        // Swap the colors
492
0
        uint c = F(y).color;
493
0
        F(y).color = F(z).color;
494
0
        F(z).color = c;
495
0
        y = z;
496
0
    } else {
497
        /*
498
                p          p            p          p
499
               /          /              \          \
500
              z    -->   x                z  -->     x
501
              |                           |
502
              x                           x
503
         */
504
0
        p = F(z).parent;
505
0
        if (x)
506
0
            F(x).parent = p;
507
0
        if (!p) {
508
0
            Q_ASSERT(head->root == z);
509
0
            head->root = x;
510
0
        } else if (F(p).left == z) {
511
0
            F(p).left = x;
512
0
            for (uint field = 0; field < Fragment::size_array_max; ++field)
513
0
                F(p).size_left_array[field] -= F(z).size_array[field];
514
0
        } else {
515
0
            F(p).right = x;
516
0
        }
517
0
    }
518
0
    uint n = z;
519
0
    while (F(n).parent) {
520
0
        uint p = F(n).parent;
521
0
        if (F(p).left == n) {
522
0
            for (uint field = 0; field < Fragment::size_array_max; ++field)
523
0
                F(p).size_left_array[field] -= F(z).size_array[field];
524
0
        }
525
0
        n = p;
526
0
    }
527
528
0
    freeFragment(z);
529
530
531
0
    if (F(y).color != Red) {
532
0
        while (F(x).parent && (x == 0 || F(x).color == Black)) {
533
0
            if (x == F(p).left) {
534
0
                uint w = F(p).right;
535
0
                if (F(w).color == Red) {
536
0
                    F(w).color = Black;
537
0
                    F(p).color = Red;
538
0
                    rotateLeft(p);
539
0
                    w = F(p).right;
540
0
                }
541
0
                if ((F(w).left == 0 || F(F(w).left).color == Black) &&
542
0
                    (F(w).right == 0 || F(F(w).right).color == Black)) {
543
0
                    F(w).color = Red;
544
0
                    x = p;
545
0
                    p = F(x).parent;
546
0
                } else {
547
0
                    if (F(w).right == 0 || F(F(w).right).color == Black) {
548
0
                        if (F(w).left)
549
0
                            F(F(w).left).color = Black;
550
0
                        F(w).color = Red;
551
0
                        rotateRight(F(p).right);
552
0
                        w = F(p).right;
553
0
                    }
554
0
                    F(w).color = F(p).color;
555
0
                    F(p).color = Black;
556
0
                    if (F(w).right)
557
0
                        F(F(w).right).color = Black;
558
0
                    rotateLeft(p);
559
0
                    break;
560
0
                }
561
0
            } else {
562
0
                uint w = F(p).left;
563
0
                if (F(w).color == Red) {
564
0
                    F(w).color = Black;
565
0
                    F(p).color = Red;
566
0
                    rotateRight(p);
567
0
                    w = F(p).left;
568
0
                }
569
0
                if ((F(w).right == 0 || F(F(w).right).color == Black) &&
570
0
                    (F(w).left == 0 || F(F(w).left).color == Black)) {
571
0
                    F(w).color = Red;
572
0
                    x = p;
573
0
                    p = F(x).parent;
574
0
                } else {
575
0
                    if (F(w).left == 0 || F(F(w).left).color == Black) {
576
0
                        if (F(w).right)
577
0
                            F(F(w).right).color = Black;
578
0
                        F(w).color = Red;
579
0
                        rotateLeft(F(p).left);
580
0
                        w = F(p).left;
581
0
                    }
582
0
                    F(w).color = F(p).color;
583
0
                    F(p).color = Black;
584
0
                    if (F(w).left)
585
0
                        F(F(w).left).color = Black;
586
0
                    rotateRight(p);
587
0
                    break;
588
0
                }
589
0
            }
590
0
        }
591
0
        if (x)
592
0
            F(x).color = Black;
593
0
    }
594
595
0
    return w;
596
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::erase_single(unsigned int)
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::erase_single(unsigned int)
597
598
template <class Fragment>
599
uint QFragmentMapData<Fragment>::findNode(int k, uint field) const
600
0
{
601
0
    Q_ASSERT(field < Fragment::size_array_max);
602
0
    uint x = root();
603
604
0
    uint s = k;
605
0
    while (x) {
606
0
        if (sizeLeft(x, field) <= s) {
607
0
            if (s < sizeLeft(x, field) + size(x, field))
608
0
                return x;
609
0
            s -= sizeLeft(x, field) + size(x, field);
610
0
            x = F(x).right;
611
0
        } else {
612
0
            x = F(x).left;
613
0
        }
614
0
    }
615
0
    return 0;
616
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::findNode(int, unsigned int) const
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::findNode(int, unsigned int) const
617
618
template <class Fragment>
619
uint QFragmentMapData<Fragment>::insert_single(int key, uint length)
620
0
{
621
0
    Q_ASSERT(!findNode(key) || (int)this->position(findNode(key)) == key);
622
623
0
    uint z = createFragment();
624
625
0
    F(z).left = 0;
626
0
    F(z).right = 0;
627
0
    F(z).size_array[0] = length;
628
0
    for (uint field = 1; field < Fragment::size_array_max; ++field)
629
0
        F(z).size_array[field] = 1;
630
0
    for (uint field = 0; field < Fragment::size_array_max; ++field)
631
0
        F(z).size_left_array[field] = 0;
632
633
0
    uint y = 0;
634
0
    uint x = root();
635
636
0
    Q_ASSERT(!x || F(x).parent == 0);
637
638
0
    uint s = key;
639
0
    bool right = false;
640
0
    while (x) {
641
0
        y = x;
642
0
        if (s <= F(x).size_left_array[0]) {
643
0
            x = F(x).left;
644
0
            right = false;
645
0
        } else {
646
0
            s -= F(x).size_left_array[0] + F(x).size_array[0];
647
0
            x = F(x).right;
648
0
            right = true;
649
0
        }
650
0
    }
651
652
0
    F(z).parent = y;
653
0
    if (!y) {
654
0
        head->root = z;
655
0
    } else if (!right) {
656
0
        F(y).left = z;
657
0
        for (uint field = 0; field < Fragment::size_array_max; ++field)
658
0
            F(y).size_left_array[field] = F(z).size_array[field];
659
0
    } else {
660
0
        F(y).right = z;
661
0
    }
662
0
    while (y && F(y).parent) {
663
0
        uint p = F(y).parent;
664
0
        if (F(p).left == y) {
665
0
            for (uint field = 0; field < Fragment::size_array_max; ++field)
666
0
                F(p).size_left_array[field] += F(z).size_array[field];
667
0
        }
668
0
        y = p;
669
0
    }
670
0
    rebalance(z);
671
672
0
    return z;
673
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::insert_single(int, unsigned int)
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::insert_single(int, unsigned int)
674
675
676
template <class Fragment>
677
0
int QFragmentMapData<Fragment>::length(uint field) const {
678
0
    uint root = this->root();
679
0
    return root ? sizeLeft(root, field) + size(root, field) + sizeRight(root, field) : 0;
680
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::length(unsigned int) const
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::length(unsigned int) const
681
682
683
template <class Fragment> // NOTE: must inherit QFragment
684
class QFragmentMap
685
{
686
public:
687
    class Iterator
688
    {
689
    public:
690
        QFragmentMap *pt;
691
        quint32 n;
692
693
        Iterator() : pt(0), n(0) {}
694
0
        Iterator(QFragmentMap *p, int node) : pt(p), n(node) {}
Unexecuted instantiation: QFragmentMap<QTextBlockData>::Iterator::Iterator(QFragmentMap<QTextBlockData>*, int)
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::Iterator::Iterator(QFragmentMap<QTextFragmentData>*, int)
695
        Iterator(const Iterator& it) : pt(it.pt), n(it.n) {}
696
697
0
        inline bool atEnd() const { return !n; }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::Iterator::atEnd() const
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::Iterator::atEnd() const
698
699
        bool operator==(const Iterator& it) const { return pt == it.pt && n == it.n; }
700
        bool operator!=(const Iterator& it) const { return pt != it.pt || n != it.n; }
701
        bool operator<(const Iterator &it) const { return position() < it.position(); }
702
703
        Fragment *operator*() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
704
        const Fragment *operator*() const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
705
0
        Fragment *operator->() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::Iterator::operator->()
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::Iterator::operator->()
706
        const Fragment *operator->() const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
707
708
0
        int position() const { Q_ASSERT(!atEnd()); return pt->data.position(n); }
709
        const Fragment *value() const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
710
0
        Fragment *value() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::Iterator::value()
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::Iterator::value()
711
712
0
        Iterator& operator++() {
713
0
            n = pt->data.next(n);
714
0
            return *this;
715
0
        }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::Iterator::operator++()
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::Iterator::operator++()
716
        Iterator& operator--() {
717
            n = pt->data.previous(n);
718
            return *this;
719
        }
720
721
    };
722
723
724
    class ConstIterator
725
    {
726
    public:
727
        const QFragmentMap *pt;
728
        quint32 n;
729
730
        /**
731
         * Functions
732
         */
733
        ConstIterator() : pt(0), n(0) {}
734
0
        ConstIterator(const QFragmentMap *p, int node) : pt(p), n(node) {}
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::ConstIterator::ConstIterator(QFragmentMap<QTextFragmentData> const*, int)
Unexecuted instantiation: QFragmentMap<QTextBlockData>::ConstIterator::ConstIterator(QFragmentMap<QTextBlockData> const*, int)
735
        ConstIterator(const ConstIterator& it) : pt(it.pt), n(it.n) {}
736
        ConstIterator(const Iterator& it) : pt(it.pt), n(it.n) {}
737
738
0
        inline bool atEnd() const { return !n; }
739
740
0
        bool operator==(const ConstIterator& it) const { return pt == it.pt && n == it.n; }
741
0
        bool operator!=(const ConstIterator& it) const { return pt != it.pt || n != it.n; }
742
        bool operator<(const ConstIterator &it) const { return position() < it.position(); }
743
744
0
        const Fragment *operator*()  const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
745
0
        const Fragment *operator->()  const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
746
747
0
        int position() const { Q_ASSERT(!atEnd()); return pt->data.position(n); }
748
0
        int size() const { Q_ASSERT(!atEnd()); return pt->data.size(n); }
749
0
        const Fragment *value() const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
750
751
0
        ConstIterator& operator++() {
752
0
            n = pt->data.next(n);
753
0
            return *this;
754
0
        }
755
        ConstIterator& operator--() {
756
            n = pt->data.previous(n);
757
            return *this;
758
        }
759
    };
760
761
762
0
    QFragmentMap() {}
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::QFragmentMap()
Unexecuted instantiation: QFragmentMap<QTextBlockData>::QFragmentMap()
763
    ~QFragmentMap()
764
0
    {
765
0
        if (!data.fragments)
766
0
            return; // in case of out-of-memory, we won't have fragments
767
0
        for (Iterator it = begin(); !it.atEnd(); ++it)
768
0
            it.value()->free();
769
0
    }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::~QFragmentMap()
Unexecuted instantiation: QFragmentMap<QTextBlockData>::~QFragmentMap()
770
771
0
    inline void clear() {
772
0
        for (Iterator it = begin(); !it.atEnd(); ++it)
773
0
            it.value()->free();
774
0
        data.init();
775
0
    }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::clear()
Unexecuted instantiation: QFragmentMap<QTextBlockData>::clear()
776
777
0
    inline Iterator begin() { return Iterator(this, data.minimum(data.root())); }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::begin()
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::begin()
778
    inline Iterator end() { return Iterator(this, 0); }
779
0
    inline ConstIterator begin() const { return ConstIterator(this, data.minimum(data.root())); }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::begin() const
Unexecuted instantiation: QFragmentMap<QTextBlockData>::begin() const
780
0
    inline ConstIterator end() const { return ConstIterator(this, 0); }
781
782
0
    inline ConstIterator last() const { return ConstIterator(this, data.maximum(data.root())); }
783
784
    inline bool isEmpty() const { return data.head->node_count == 0; }
785
0
    inline int numNodes() const { return data.head->node_count; }
786
0
    int length(uint field = 0) const { return data.length(field); }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::length(unsigned int) const
Unexecuted instantiation: QFragmentMap<QTextBlockData>::length(unsigned int) const
787
788
0
    Iterator find(int k, uint field = 0) { return Iterator(this, data.findNode(k, field)); }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::find(int, unsigned int)
Unexecuted instantiation: QFragmentMap<QTextBlockData>::find(int, unsigned int)
789
0
    ConstIterator find(int k, uint field = 0) const { return ConstIterator(this, data.findNode(k, field)); }
790
791
0
    uint findNode(int k, uint field = 0) const { return data.findNode(k, field); }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::findNode(int, unsigned int) const
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::findNode(int, unsigned int) const
792
793
    uint insert_single(int key, uint length)
794
0
    {
795
0
        uint f = data.insert_single(key, length);
796
0
        if (f != 0) {
797
0
            Fragment *frag = fragment(f);
798
0
            Q_ASSERT(frag);
799
0
            frag->initialize();
800
0
        }
801
0
        return f;
802
0
    }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::insert_single(int, unsigned int)
Unexecuted instantiation: QFragmentMap<QTextBlockData>::insert_single(int, unsigned int)
803
    uint erase_single(uint f)
804
0
    {
805
0
      if (f != 0) {
806
0
          Fragment *frag = fragment(f);
807
0
          Q_ASSERT(frag);
808
0
          frag->free();
809
0
      }
810
0
      return data.erase_single(f);
811
0
    }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::erase_single(unsigned int)
Unexecuted instantiation: QFragmentMap<QTextBlockData>::erase_single(unsigned int)
812
813
0
    inline Fragment *fragment(uint index) {
814
0
        Q_ASSERT(index != 0);
815
0
        return data.fragment(index);
816
0
    }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::fragment(unsigned int)
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::fragment(unsigned int)
817
0
    inline const Fragment *fragment(uint index) const {
818
0
        Q_ASSERT(index != 0);
819
0
        return data.fragment(index);
820
0
    }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::fragment(unsigned int) const
Unexecuted instantiation: QFragmentMap<QTextBlockData>::fragment(unsigned int) const
821
0
    inline uint position(uint node, uint field = 0) const { return data.position(node, field); }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::position(unsigned int, unsigned int) const
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::position(unsigned int, unsigned int) const
822
0
    inline bool isValid(uint n) const { return data.isValid(n); }
823
0
    inline uint next(uint n) const { return data.next(n); }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::next(unsigned int) const
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::next(unsigned int) const
824
0
    inline uint previous(uint n) const { return data.previous(n); }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::previous(unsigned int) const
Unexecuted instantiation: QFragmentMap<QTextBlockData>::previous(unsigned int) const
825
0
    inline uint size(uint node, uint field = 0) const { return data.size(node, field); }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::size(unsigned int, unsigned int) const
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::size(unsigned int, unsigned int) const
826
    inline void setSize(uint node, int new_size, uint field = 0)
827
0
        { data.setSize(node, new_size, field);
828
0
      if (node != 0 && field == 0) {
829
0
          Fragment *frag = fragment(node);
830
0
          Q_ASSERT(frag);
831
0
          frag->invalidate();
832
0
      }
833
0
    }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::setSize(unsigned int, int, unsigned int)
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::setSize(unsigned int, int, unsigned int)
834
835
0
    inline int firstNode() const { return data.minimum(data.root()); }
836
837
private:
838
    friend class Iterator;
839
    friend class ConstIterator;
840
841
    QFragmentMapData<Fragment> data;
842
843
    QFragmentMap(const QFragmentMap& m);
844
    QFragmentMap& operator= (const QFragmentMap& m);
845
};
846
847
QT_END_NAMESPACE
848
849
#endif // QFRAGMENTMAP_P_H