source: trunk/src/gui/text/qfragmentmap_p.h@ 371

Last change on this file since 371 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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