gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Avoid STL panic at Elevator when compiled with -D_GLIBCXX_DEBUG
0 1 0
default
1 file changed with 7 insertions and 7 deletions:
↑ Collapse diff ↑
Ignore white space 768 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_ELEVATOR_H
20 20
#define LEMON_ELEVATOR_H
21 21

	
22 22
///\ingroup auxdat
23 23
///\file
24 24
///\brief Elevator class
25 25
///
26 26
///Elevator class implements an efficient data structure
27 27
///for labeling items in push-relabel type algorithms.
28 28
///
29 29

	
30 30
#include <test/test_tools.h>
31 31
namespace lemon {
32 32

	
33 33
  ///Class for handling "labels" in push-relabel type algorithms.
34 34

	
35 35
  ///A class for handling "labels" in push-relabel type algorithms.
36 36
  ///
37 37
  ///\ingroup auxdat
38 38
  ///Using this class you can assign "labels" (nonnegative integer numbers)
39 39
  ///to the edges or nodes of a graph, manipulate and query them through
40 40
  ///operations typically arising in "push-relabel" type algorithms.
41 41
  ///
42 42
  ///Each item is either \em active or not, and you can also choose a
43 43
  ///highest level active item.
44 44
  ///
45 45
  ///\sa LinkedElevator
46 46
  ///
47 47
  ///\param Graph the underlying graph type
48 48
  ///\param Item Type of the items the data is assigned to (Graph::Node,
49 49
  ///Graph::Edge, Graph::UEdge)
50 50
  template<class Graph, class Item>
51 51
  class Elevator
52 52
  {
53 53
  public:
54 54

	
55 55
    typedef Item Key;
56 56
    typedef int Value;
57 57

	
58 58
  private:
59 59

	
60
    typedef typename std::vector<Item>::iterator Vit;
60
    typedef Item *Vit;
61 61
    typedef typename ItemSetTraits<Graph,Item>::template Map<Vit>::Type VitMap;
62 62
    typedef typename ItemSetTraits<Graph,Item>::template Map<int>::Type IntMap;
63 63

	
64 64
    const Graph &_g;
65 65
    int _max_level;
66 66
    int _item_num;
67 67
    VitMap _where;
68 68
    IntMap _level;
69 69
    std::vector<Item> _items;
70 70
    std::vector<Vit> _first;
71 71
    std::vector<Vit> _last_active;
72 72

	
73 73
    int _highest_active;
74 74

	
75 75
    void copy(Item i, Vit p)
76 76
    {
77 77
      _where[*p=i]=p;
78 78
    }
79 79
    void copy(Vit s, Vit p)
80 80
    {
81 81
      if(s!=p)
82 82
        {
83 83
          Item i=*s;
84 84
          *p=i;
85 85
          _where[i]=p;
86 86
        }
87 87
    }
88 88
    void swap(Vit i, Vit j)
89 89
    {
90 90
      Item ti=*i;
91 91
      Vit ct = _where[ti];
92 92
      _where[ti]=_where[*i=*j];
93 93
      _where[*j]=ct;
94 94
      *j=ti;
95 95
    }
96 96

	
97 97
  public:
98 98

	
99 99
    ///Constructor with given maximum level.
100 100

	
101 101
    ///Constructor with given maximum level.
102 102
    ///
103 103
    ///\param g The underlying graph
104 104
    ///\param max_level Set the range of the possible labels to
105 105
    ///[0...\c max_level]
106 106
    Elevator(const Graph &g,int max_level) :
107 107
      _g(g),
108 108
      _max_level(max_level),
109 109
      _item_num(_max_level),
110 110
      _where(g),
111 111
      _level(g,0),
112 112
      _items(_max_level),
113 113
      _first(_max_level+2),
114 114
      _last_active(_max_level+2),
115 115
      _highest_active(-1) {}
116 116
    ///Constructor.
117 117

	
118 118
    ///Constructor.
119 119
    ///
120 120
    ///\param g The underlying graph
121 121
    ///The range of the possible labels is [0...\c max_level],
122 122
    ///where \c max_level is equal to the number of labeled items in the graph.
123 123
    Elevator(const Graph &g) :
124 124
      _g(g),
125 125
      _max_level(countItems<Graph, Item>(g)),
126 126
      _item_num(_max_level),
127 127
      _where(g),
128 128
      _level(g,0),
129 129
      _items(_max_level),
130 130
      _first(_max_level+2),
131 131
      _last_active(_max_level+2),
132 132
      _highest_active(-1)
133 133
    {
134 134
    }
135 135

	
136 136
    ///Activate item \c i.
137 137

	
138 138
    ///Activate item \c i.
139 139
    ///\pre Item \c i shouldn't be active before.
140 140
    void activate(Item i)
141 141
    {
142 142
      const int l=_level[i];
143 143
      swap(_where[i],++_last_active[l]);
144 144
      if(l>_highest_active) _highest_active=l;
145 145
    }
146 146

	
147 147
    ///Deactivate item \c i.
148 148

	
149 149
    ///Deactivate item \c i.
150 150
    ///\pre Item \c i must be active before.
151 151
    void deactivate(Item i)
152 152
    {
153 153
      swap(_where[i],_last_active[_level[i]]--);
154 154
      while(_highest_active>=0 &&
155 155
            _last_active[_highest_active]<_first[_highest_active])
156 156
        _highest_active--;
157 157
    }
158 158

	
159 159
    ///Query whether item \c i is active
160 160
    bool active(Item i) const { return _where[i]<=_last_active[_level[i]]; }
161 161

	
162 162
    ///Return the level of item \c i.
163 163
    int operator[](Item i) const { return _level[i]; }
164 164

	
165 165
    ///Return the number of items on level \c l.
166 166
    int onLevel(int l) const
167 167
    {
168 168
      return _first[l+1]-_first[l];
169 169
    }
170 170
    ///Return true if the level is empty.
171 171
    bool emptyLevel(int l) const
172 172
    {
173 173
      return _first[l+1]-_first[l]==0;
174 174
    }
175 175
    ///Return the number of items above level \c l.
176 176
    int aboveLevel(int l) const
177 177
    {
178 178
      return _first[_max_level+1]-_first[l+1];
179 179
    }
180 180
    ///Return the number of active items on level \c l.
181 181
    int activesOnLevel(int l) const
182 182
    {
183 183
      return _last_active[l]-_first[l]+1;
184 184
    }
185 185
    ///Return true if there is not active item on level \c l.
186 186
    bool activeFree(int l) const
187 187
    {
188 188
      return _last_active[l]<_first[l];
189 189
    }
190 190
    ///Return the maximum allowed level.
191 191
    int maxLevel() const
192 192
    {
193 193
      return _max_level;
194 194
    }
195 195

	
196 196
    ///\name Highest Active Item
197 197
    ///Functions for working with the highest level
198 198
    ///active item.
199 199

	
200 200
    ///@{
201 201

	
202 202
    ///Return a highest level active item.
203 203

	
204 204
    ///Return a highest level active item.
205 205
    ///
206 206
    ///\return the highest level active item or INVALID if there is no active
207 207
    ///item.
208 208
    Item highestActive() const
209 209
    {
210 210
      return _highest_active>=0?*_last_active[_highest_active]:INVALID;
211 211
    }
212 212

	
213 213
    ///Return a highest active level.
214 214

	
215 215
    ///Return a highest active level.
216 216
    ///
217 217
    ///\return the level of the highest active item or -1 if there is no active
218 218
    ///item.
219 219
    int highestActiveLevel() const
220 220
    {
221 221
      return _highest_active;
222 222
    }
223 223

	
224 224
    ///Lift the highest active item by one.
225 225

	
226 226
    ///Lift the item returned by highestActive() by one.
227 227
    ///
228 228
    void liftHighestActive()
229 229
    {
230 230
      ++_level[*_last_active[_highest_active]];
231 231
      swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
232 232
      --_first[++_highest_active];
233 233
    }
234 234

	
235 235
    ///Lift the highest active item.
236 236

	
237 237
    ///Lift the item returned by highestActive() to level \c new_level.
238 238
    ///
239 239
    ///\warning \c new_level must be strictly higher
240 240
    ///than the current level.
241 241
    ///
242 242
    void liftHighestActive(int new_level)
243 243
    {
244 244
      const Item li = *_last_active[_highest_active];
245 245

	
246 246
      copy(--_first[_highest_active+1],_last_active[_highest_active]--);
247 247
      for(int l=_highest_active+1;l<new_level;l++)
248 248
        {
249 249
          copy(--_first[l+1],_first[l]);
250 250
          --_last_active[l];
251 251
        }
252 252
      copy(li,_first[new_level]);
253 253
      _level[li]=new_level;
254 254
      _highest_active=new_level;
255 255
    }
256 256

	
257 257
    ///Lift the highest active item.
258 258

	
259 259
    ///Lift the item returned by highestActive() to the top level and
260 260
    ///deactivates it.
261 261
    ///
262 262
    ///\warning \c new_level must be strictly higher
263 263
    ///than the current level.
264 264
    ///
265 265
    void liftHighestActiveToTop()
266 266
    {
267 267
      const Item li = *_last_active[_highest_active];
268 268

	
269 269
      copy(--_first[_highest_active+1],_last_active[_highest_active]--);
270 270
      for(int l=_highest_active+1;l<_max_level;l++)
271 271
        {
272 272
          copy(--_first[l+1],_first[l]);
273 273
          --_last_active[l];
274 274
        }
275 275
      copy(li,_first[_max_level]);
276 276
      --_last_active[_max_level];
277 277
      _level[li]=_max_level;
278 278

	
279 279
      while(_highest_active>=0 &&
280 280
            _last_active[_highest_active]<_first[_highest_active])
281 281
        _highest_active--;
282 282
    }
283 283

	
284 284
    ///@}
285 285

	
286 286
    ///\name Active Item on Certain Level
287 287
    ///Functions for working with the active items.
288 288

	
289 289
    ///@{
290 290

	
291 291
    ///Returns an active item on level \c l.
292 292

	
293 293
    ///Returns an active item on level \c l.
294 294
    ///
295 295
    ///Returns an active item on level \c l or \ref INVALID if there is no such
296 296
    ///an item. (\c l must be from the range [0...\c max_level].
297 297
    Item activeOn(int l) const
298 298
    {
299 299
      return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
300 300
    }
301 301

	
302 302
    ///Lifts the active item returned by \c activeOn() member function.
303 303

	
304 304
    ///Lifts the active item returned by \c activeOn() member function
305 305
    ///by one.
306 306
    Item liftActiveOn(int level)
307 307
    {
308 308
      ++_level[*_last_active[level]];
309 309
      swap(_last_active[level]--, --_first[level+1]);
310 310
      if (level+1>_highest_active) ++_highest_active;
311 311
    }
312 312

	
313 313
    ///Lifts the active item returned by \c activeOn() member function.
314 314

	
315 315
    ///Lifts the active item returned by \c activeOn() member function
316 316
    ///to the given level.
317 317
    void liftActiveOn(int level, int new_level)
318 318
    {
319 319
      const Item ai = *_last_active[level];
320 320

	
321 321
      copy(--_first[level+1], _last_active[level]--);
322 322
      for(int l=level+1;l<new_level;l++)
323 323
        {
324 324
          copy(_last_active[l],_first[l]);
325 325
          copy(--_first[l+1], _last_active[l]--);
326 326
        }
327 327
      copy(ai,_first[new_level]);
328 328
      _level[ai]=new_level;
329 329
      if (new_level>_highest_active) _highest_active=new_level;
330 330
    }
331 331

	
332 332
    ///Lifts the active item returned by \c activeOn() member function.
333 333

	
334 334
    ///Lifts the active item returned by \c activeOn() member function
335 335
    ///to the top level.
336 336
    void liftActiveToTop(int level)
337 337
    {
338 338
      const Item ai = *_last_active[level];
339 339

	
340 340
      copy(--_first[level+1],_last_active[level]--);
341 341
      for(int l=level+1;l<_max_level;l++)
342 342
        {
343 343
          copy(_last_active[l],_first[l]);
344 344
          copy(--_first[l+1], _last_active[l]--);
345 345
        }
346 346
      copy(ai,_first[_max_level]);
347 347
      --_last_active[_max_level];
348 348
      _level[ai]=_max_level;
349 349

	
350 350
      if (_highest_active==level) {
351 351
        while(_highest_active>=0 &&
352 352
              _last_active[_highest_active]<_first[_highest_active])
353 353
          _highest_active--;
354 354
      }
355 355
    }
356 356

	
357 357
    ///@}
358 358

	
359 359
    ///Lift an active item to a higher level.
360 360

	
361 361
    ///Lift an active item to a higher level.
362 362
    ///\param i The item to be lifted. It must be active.
363 363
    ///\param new_level The new level of \c i. It must be strictly higher
364 364
    ///than the current level.
365 365
    ///
366 366
    void lift(Item i, int new_level)
367 367
    {
368 368
      const int lo = _level[i];
369 369
      const Vit w = _where[i];
370 370

	
371 371
      copy(_last_active[lo],w);
372 372
      copy(--_first[lo+1],_last_active[lo]--);
373 373
      for(int l=lo+1;l<new_level;l++)
374 374
        {
375 375
          copy(_last_active[l],_first[l]);
376 376
          copy(--_first[l+1],_last_active[l]--);
377 377
        }
378 378
      copy(i,_first[new_level]);
379 379
      _level[i]=new_level;
380 380
      if(new_level>_highest_active) _highest_active=new_level;
381 381
    }
382 382

	
383 383
    ///Move an inactive item to the top but one level (in a dirty way).
384 384

	
385 385
    ///This function moves an inactive item to the top but one level.
386 386
    ///It makes the underlying datastructure corrupt, so use is only if
387 387
    ///you really know what it is for.
388 388
    ///\pre The item is on the top level.
389 389
    void dirtyTopButOne(Item i) {
390 390
      _level[i] = _max_level - 1;
391 391
    }
392 392

	
393 393
    ///Lift all items on and above a level to the top (and deactivate them).
394 394

	
395 395
    ///This function lifts all items on and above level \c l to \c
396 396
    ///maxLevel(), and also deactivates them.
397 397
    void liftToTop(int l)
398 398
    {
399 399
      const Vit f=_first[l];
400 400
      const Vit tl=_first[_max_level];
401 401
      for(Vit i=f;i!=tl;++i)
402 402
        _level[*i]=_max_level;
403 403
      for(int i=l;i<=_max_level;i++)
404 404
        {
405 405
          _first[i]=f;
406 406
          _last_active[i]=f-1;
407 407
        }
408 408
      for(_highest_active=l-1;
409 409
          _highest_active>=0 &&
410 410
            _last_active[_highest_active]<_first[_highest_active];
411 411
          _highest_active--) ;
412 412
    }
413 413

	
414 414
  private:
415 415
    int _init_lev;
416 416
    Vit _init_num;
417 417

	
418 418
  public:
419 419

	
420 420
    ///\name Initialization
421 421
    ///Using this function you can initialize the levels of the item.
422 422
    ///\n
423 423
    ///This initializatios is started with calling \c initStart().
424 424
    ///Then the
425 425
    ///items should be listed levels by levels statring with the lowest one
426 426
    ///(with level 0). This is done by using \c initAddItem()
427 427
    ///and \c initNewLevel(). Finally \c initFinish() must be called.
428 428
    ///The items not listed will be put on the highest level.
429 429
    ///@{
430 430

	
431 431
    ///Start the initialization process.
432 432

	
433 433
    void initStart()
434 434
    {
435 435
      _init_lev=0;
436
      _init_num=_items.begin();
437
      _first[0]=_items.begin();
438
      _last_active[0]=_items.begin()-1;
439
      Vit n=_items.begin();
436
      _init_num=&_items[0];
437
      _first[0]=&_items[0];
438
      _last_active[0]=&_items[0]-1;
439
      Vit n=&_items[0];
440 440
      for(typename ItemSetTraits<Graph,Item>::ItemIt i(_g);i!=INVALID;++i)
441 441
        {
442 442
          *n=i;
443 443
          _where[i]=n;
444 444
          _level[i]=_max_level;
445 445
          ++n;
446 446
        }
447 447
    }
448 448

	
449 449
    ///Add an item to the current level.
450 450

	
451 451
    void initAddItem(Item i)
452 452
    {
453 453
     swap(_where[i],_init_num);
454 454
      _level[i]=_init_lev;
455 455
      ++_init_num;
456 456
    }
457 457

	
458 458
    ///Start a new level.
459 459

	
460 460
    ///Start a new level.
461 461
    ///It shouldn't be used before the items on level 0 are listed.
462 462
    void initNewLevel()
463 463
    {
464 464
      _init_lev++;
465 465
      _first[_init_lev]=_init_num;
466 466
      _last_active[_init_lev]=_init_num-1;
467 467
    }
468 468

	
469 469
    ///Finalize the initialization process.
470 470

	
471 471
    void initFinish()
472 472
    {
473 473
      for(_init_lev++;_init_lev<=_max_level;_init_lev++)
474 474
        {
475 475
          _first[_init_lev]=_init_num;
476 476
          _last_active[_init_lev]=_init_num-1;
477 477
        }
478
      _first[_max_level+1]=_items.begin()+_item_num;
479
      _last_active[_max_level+1]=_items.begin()+_item_num-1;
478
      _first[_max_level+1]=&_items[0]+_item_num;
479
      _last_active[_max_level+1]=&_items[0]+_item_num-1;
480 480
      _highest_active = -1;
481 481
    }
482 482

	
483 483
    ///@}
484 484

	
485 485
  };
486 486

	
487 487
  ///Class for handling "labels" in push-relabel type algorithms.
488 488

	
489 489
  ///A class for handling "labels" in push-relabel type algorithms.
490 490
  ///
491 491
  ///\ingroup auxdat
492 492
  ///Using this class you can assign "labels" (nonnegative integer numbers)
493 493
  ///to the edges or nodes of a graph, manipulate and query them through
494 494
  ///operations typically arising in "push-relabel" type algorithms.
495 495
  ///
496 496
  ///Each item is either \em active or not, and you can also choose a
497 497
  ///highest level active item.
498 498
  ///
499 499
  ///\sa Elevator
500 500
  ///
501 501
  ///\param Graph the underlying graph type
502 502
  ///\param Item Type of the items the data is assigned to (Graph::Node,
503 503
  ///Graph::Edge, Graph::UEdge)
504 504
  template <class Graph, class Item>
505 505
  class LinkedElevator {
506 506
  public:
507 507

	
508 508
    typedef Item Key;
509 509
    typedef int Value;
510 510

	
511 511
  private:
512 512

	
513 513
    typedef typename ItemSetTraits<Graph,Item>::
514 514
    template Map<Item>::Type ItemMap;
515 515
    typedef typename ItemSetTraits<Graph,Item>::
516 516
    template Map<int>::Type IntMap;
517 517
    typedef typename ItemSetTraits<Graph,Item>::
518 518
    template Map<bool>::Type BoolMap;
519 519

	
520 520
    const Graph &_graph;
521 521
    int _max_level;
522 522
    int _item_num;
523 523
    std::vector<Item> _first, _last;
524 524
    ItemMap _prev, _next;
525 525
    int _highest_active;
526 526
    IntMap _level;
527 527
    BoolMap _active;
528 528

	
529 529
  public:
530 530
    ///Constructor with given maximum level.
531 531

	
532 532
    ///Constructor with given maximum level.
533 533
    ///
534 534
    ///\param g The underlying graph
535 535
    ///\param max_level Set the range of the possible labels to
536 536
    ///[0...\c max_level]
537 537
    LinkedElevator(const Graph& graph, int max_level)
538 538
      : _graph(graph), _max_level(max_level), _item_num(_max_level),
539 539
        _first(_max_level + 1), _last(_max_level + 1),
540 540
        _prev(graph), _next(graph),
541 541
        _highest_active(-1), _level(graph), _active(graph) {}
542 542

	
543 543
    ///Constructor.
544 544

	
545 545
    ///Constructor.
546 546
    ///
547 547
    ///\param g The underlying graph
548 548
    ///The range of the possible labels is [0...\c max_level],
549 549
    ///where \c max_level is equal to the number of labeled items in the graph.
550 550
    LinkedElevator(const Graph& graph)
551 551
      : _graph(graph), _max_level(countItems<Graph, Item>(graph)),
552 552
        _item_num(_max_level),
553 553
        _first(_max_level + 1), _last(_max_level + 1),
554 554
        _prev(graph, INVALID), _next(graph, INVALID),
555 555
        _highest_active(-1), _level(graph), _active(graph) {}
556 556

	
557 557

	
558 558
    ///Activate item \c i.
559 559

	
560 560
    ///Activate item \c i.
561 561
    ///\pre Item \c i shouldn't be active before.
562 562
    void activate(Item i) {
563 563
      _active.set(i, true);
564 564

	
565 565
      int level = _level[i];
566 566
      if (level > _highest_active) {
567 567
        _highest_active = level;
568 568
      }
569 569

	
570 570
      if (_prev[i] == INVALID || _active[_prev[i]]) return;
571 571
      //unlace
572 572
      _next.set(_prev[i], _next[i]);
573 573
      if (_next[i] != INVALID) {
574 574
        _prev.set(_next[i], _prev[i]);
575 575
      } else {
576 576
        _last[level] = _prev[i];
577 577
      }
578 578
      //lace
579 579
      _next.set(i, _first[level]);
580 580
      _prev.set(_first[level], i);
581 581
      _prev.set(i, INVALID);
582 582
      _first[level] = i;
583 583

	
584 584
    }
585 585

	
586 586
    ///Deactivate item \c i.
587 587

	
588 588
    ///Deactivate item \c i.
589 589
    ///\pre Item \c i must be active before.
590 590
    void deactivate(Item i) {
591 591
      _active.set(i, false);
592 592
      int level = _level[i];
593 593

	
594 594
      if (_next[i] == INVALID || !_active[_next[i]])
595 595
        goto find_highest_level;
596 596

	
597 597
      //unlace
598 598
      _prev.set(_next[i], _prev[i]);
599 599
      if (_prev[i] != INVALID) {
600 600
        _next.set(_prev[i], _next[i]);
601 601
      } else {
602 602
        _first[_level[i]] = _next[i];
603 603
      }
604 604
      //lace
605 605
      _prev.set(i, _last[level]);
606 606
      _next.set(_last[level], i);
607 607
      _next.set(i, INVALID);
608 608
      _last[level] = i;
609 609

	
610 610
    find_highest_level:
611 611
      if (level == _highest_active) {
612 612
        while (_highest_active >= 0 && activeFree(_highest_active))
613 613
          --_highest_active;
614 614
      }
615 615
    }
616 616

	
617 617
    ///Query whether item \c i is active
618 618
    bool active(Item i) const { return _active[i]; }
619 619

	
620 620
    ///Return the level of item \c i.
621 621
    int operator[](Item i) const { return _level[i]; }
622 622

	
623 623
    ///Return the number of items on level \c l.
624 624
    int onLevel(int l) const {
625 625
      int num = 0;
626 626
      Item n = _first[l];
627 627
      while (n != INVALID) {
628 628
        ++num;
629 629
        n = _next[n];
630 630
      }
631 631
      return num;
632 632
    }
633 633

	
634 634
    ///Return true if the level is empty.
635 635
    bool emptyLevel(int l) const {
636 636
      return _first[l] == INVALID;
637 637
    }
638 638

	
639 639
    ///Return the number of items above level \c l.
640 640
    int aboveLevel(int l) const {
641 641
      int num = 0;
642 642
      for (int level = l + 1; level < _max_level; ++level)
643 643
        num += onLevel(level);
644 644
      return num;
645 645
    }
646 646

	
647 647
    ///Return the number of active items on level \c l.
648 648
    int activesOnLevel(int l) const {
649 649
      int num = 0;
650 650
      Item n = _first[l];
651 651
      while (n != INVALID && _active[n]) {
652 652
        ++num;
653 653
        n = _next[n];
654 654
      }
655 655
      return num;
656 656
    }
657 657

	
658 658
    ///Return true if there is not active item on level \c l.
659 659
    bool activeFree(int l) const {
660 660
      return _first[l] == INVALID || !_active[_first[l]];
661 661
    }
662 662

	
663 663
    ///Return the maximum allowed level.
664 664
    int maxLevel() const {
665 665
      return _max_level;
666 666
    }
667 667

	
668 668
    ///\name Highest Active Item
669 669
    ///Functions for working with the highest level
670 670
    ///active item.
671 671

	
672 672
    ///@{
673 673

	
674 674
    ///Return a highest level active item.
675 675

	
676 676
    ///Return a highest level active item.
677 677
    ///
678 678
    ///\return the highest level active item or INVALID if there is no
679 679
    ///active item.
680 680
    Item highestActive() const {
681 681
      return _highest_active >= 0 ? _first[_highest_active] : INVALID;
682 682
    }
683 683

	
684 684
    ///Return a highest active level.
685 685

	
686 686
    ///Return a highest active level.
687 687
    ///
688 688
    ///\return the level of the highest active item or -1 if there is
689 689
    ///no active item.
690 690
    int highestActiveLevel() const {
691 691
      return _highest_active;
692 692
    }
693 693

	
694 694
    ///Lift the highest active item by one.
695 695

	
696 696
    ///Lift the item returned by highestActive() by one.
697 697
    ///
698 698
    void liftHighestActive() {
699 699
      Item i = _first[_highest_active];
700 700
      if (_next[i] != INVALID) {
701 701
        _prev.set(_next[i], INVALID);
702 702
        _first[_highest_active] = _next[i];
703 703
      } else {
704 704
        _first[_highest_active] = INVALID;
705 705
        _last[_highest_active] = INVALID;
706 706
      }
707 707
      _level.set(i, ++_highest_active);
708 708
      if (_first[_highest_active] == INVALID) {
709 709
        _first[_highest_active] = i;
710 710
        _last[_highest_active] = i;
711 711
        _prev.set(i, INVALID);
712 712
        _next.set(i, INVALID);
713 713
      } else {
714 714
        _prev.set(_first[_highest_active], i);
715 715
        _next.set(i, _first[_highest_active]);
716 716
        _first[_highest_active] = i;
717 717
      }
718 718
    }
719 719

	
720 720
    ///Lift the highest active item.
721 721

	
722 722
    ///Lift the item returned by highestActive() to level \c new_level.
723 723
    ///
724 724
    ///\warning \c new_level must be strictly higher
725 725
    ///than the current level.
726 726
    ///
727 727
    void liftHighestActive(int new_level) {
728 728
      Item i = _first[_highest_active];
729 729
      if (_next[i] != INVALID) {
730 730
        _prev.set(_next[i], INVALID);
731 731
        _first[_highest_active] = _next[i];
732 732
      } else {
733 733
        _first[_highest_active] = INVALID;
734 734
        _last[_highest_active] = INVALID;
735 735
      }
736 736
      _level.set(i, _highest_active = new_level);
737 737
      if (_first[_highest_active] == INVALID) {
738 738
        _first[_highest_active] = _last[_highest_active] = i;
739 739
        _prev.set(i, INVALID);
740 740
        _next.set(i, INVALID);
741 741
      } else {
742 742
        _prev.set(_first[_highest_active], i);
743 743
        _next.set(i, _first[_highest_active]);
744 744
        _first[_highest_active] = i;
745 745
      }
746 746
    }
747 747

	
748 748
    ///Lift the highest active to top.
749 749

	
750 750
    ///Lift the item returned by highestActive() to the top level and
751 751
    ///deactivates the item.
752 752
    ///
753 753
    void liftHighestActiveToTop() {
754 754
      Item i = _first[_highest_active];
755 755
      _level.set(i, _max_level);
756 756
      if (_next[i] != INVALID) {
757 757
        _prev.set(_next[i], INVALID);
758 758
        _first[_highest_active] = _next[i];
759 759
      } else {
760 760
        _first[_highest_active] = INVALID;
761 761
        _last[_highest_active] = INVALID;
762 762
      }
763 763
      while (_highest_active >= 0 && activeFree(_highest_active))
764 764
        --_highest_active;
765 765
    }
766 766

	
767 767
    ///@}
768 768

	
769 769
    ///\name Active Item on Certain Level
770 770
    ///Functions for working with the active items.
771 771

	
772 772
    ///@{
773 773

	
774 774
    ///Returns an active item on level \c l.
775 775

	
776 776
    ///Returns an active item on level \c l.
777 777
    ///
778 778
    ///Returns an active item on level \c l or \ref INVALID if there is no such
779 779
    ///an item. (\c l must be from the range [0...\c max_level].
780 780
    Item activeOn(int l) const
781 781
    {
782 782
      return _active[_first[l]] ? _first[l] : INVALID;
783 783
    }
784 784

	
785 785
    ///Lifts the active item returned by \c activeOn() member function.
786 786

	
787 787
    ///Lifts the active item returned by \c activeOn() member function
788 788
    ///by one.
789 789
    Item liftActiveOn(int l)
790 790
    {
791 791
      Item i = _first[l];
792 792
      if (_next[i] != INVALID) {
793 793
        _prev.set(_next[i], INVALID);
794 794
        _first[l] = _next[i];
795 795
      } else {
796 796
        _first[l] = INVALID;
797 797
        _last[l] = INVALID;
798 798
      }
799 799
      _level.set(i, ++l);
800 800
      if (_first[l] == INVALID) {
801 801
        _first[l] = _last[l] = i;
802 802
        _prev.set(i, INVALID);
803 803
        _next.set(i, INVALID);
804 804
      } else {
805 805
        _prev.set(_first[l], i);
806 806
        _next.set(i, _first[l]);
807 807
        _first[l] = i;
808 808
      }
809 809
      if (_highest_active < l) {
810 810
        _highest_active = l;
811 811
      }
812 812
    }
813 813

	
814 814
    /// \brief Lifts the active item returned by \c activeOn() member function.
815 815
    ///
816 816
    /// Lifts the active item returned by \c activeOn() member function
817 817
    /// to the given level.
818 818
    void liftActiveOn(int l, int new_level)
819 819
    {
820 820
      Item i = _first[l];
821 821
      if (_next[i] != INVALID) {
822 822
        _prev.set(_next[i], INVALID);
823 823
        _first[l] = _next[i];
824 824
      } else {
825 825
        _first[l] = INVALID;
826 826
        _last[l] = INVALID;
827 827
      }
828 828
      _level.set(i, l = new_level);
829 829
      if (_first[l] == INVALID) {
830 830
        _first[l] = _last[l] = i;
831 831
        _prev.set(i, INVALID);
832 832
        _next.set(i, INVALID);
833 833
      } else {
834 834
        _prev.set(_first[l], i);
835 835
        _next.set(i, _first[l]);
836 836
        _first[l] = i;
837 837
      }
838 838
      if (_highest_active < l) {
839 839
        _highest_active = l;
840 840
      }
841 841
    }
842 842

	
843 843
    ///Lifts the active item returned by \c activeOn() member function.
844 844

	
845 845
    ///Lifts the active item returned by \c activeOn() member function
846 846
    ///to the top level.
847 847
    void liftActiveToTop(int l)
848 848
    {
849 849
      Item i = _first[l];
850 850
      if (_next[i] != INVALID) {
851 851
        _prev.set(_next[i], INVALID);
852 852
        _first[l] = _next[i];
853 853
      } else {
854 854
        _first[l] = INVALID;
855 855
        _last[l] = INVALID;
856 856
      }
857 857
      _level.set(i, _max_level);
858 858
      if (l == _highest_active) {
859 859
        while (_highest_active >= 0 && activeFree(_highest_active))
860 860
          --_highest_active;
861 861
      }
862 862
    }
863 863

	
0 comments (0 inline)