PackedListI.H 22.5 KB
Newer Older
1
2
3
4
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
5
    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
6
     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
7
8
9
10
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

11
12
13
14
    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
15
16
17
18
19
20
21

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
22
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
23
24
25

\*---------------------------------------------------------------------------*/

Mark Olesen's avatar
Mark Olesen committed
26
#include <climits>
27

28
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
29

30
template<unsigned nBits>
31
inline constexpr unsigned int Foam::PackedList<nBits>::max_bits()
32
{
Mark Olesen's avatar
Mark Olesen committed
33
    return sizeof(StorageType)*CHAR_BIT - 1;
34
35
}

36

37
template<unsigned nBits>
38
inline constexpr unsigned int Foam::PackedList<nBits>::max_value()
39
{
40
    return (1u << nBits) - 1;
41
42
43
}


44
template<unsigned nBits>
45
inline constexpr unsigned int Foam::PackedList<nBits>::packing()
46
{
Mark Olesen's avatar
Mark Olesen committed
47
    return sizeof(StorageType)*CHAR_BIT / nBits;
48
49
50
}


51
template<unsigned nBits>
52
53
54
55
inline constexpr unsigned int Foam::PackedList<nBits>::maskLower
(
    unsigned offset
)
Mark Olesen's avatar
Mark Olesen committed
56
{
57
    // Return (1u << (nBits * offset)) - 1;
58
59
    // The next one works more reliably with overflows
    // eg, when compiled without optimization
60
    return (~0u >> (sizeof(StorageType)*CHAR_BIT - nBits * offset));
Mark Olesen's avatar
Mark Olesen committed
61
62
63
}


64
template<unsigned nBits>
65
66
67
68
inline constexpr Foam::label Foam::PackedList<nBits>::packedLength
(
    const label nElem
)
69
{
70
    return (nElem + packing() - 1) / packing();
71
72
73
}


74
75
// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
namespace Foam
{
    // Template specialization for bool entries
    template<>
    inline unsigned int Foam::PackedList<1>::readValue(Istream& is)
    {
        return readBool(is);
    }

    // Template specialization for bool entries
    template<>
    inline void Foam::PackedList<1>::setPair(Istream& is)
    {
        set(readLabel(is), true);
    }

    // Template specialization for bool entries
    template<>
    inline bool Foam::PackedList<1>::iteratorBase::writeIfSet(Ostream& os) const
    {
        if (this->get())
        {
            os  << index_;
            return true;
        }
101
102

        return false;
103
104
105
106
107
108
109
110
111
112
113
    }
}


template<unsigned nBits>
inline unsigned int Foam::PackedList<nBits>::readValue(Istream& is)
{
    const unsigned int val = readLabel(is);

    if (val > max_value())
    {
114
        FatalIOErrorInFunction(is)
115
116
117
118
119
120
121
122
123
124
125
126
            << "Out-of-range value " << val << " for PackedList<" << nBits
            << ">. Maximum permitted value is " << max_value() << "."
            << exit(FatalIOError);
    }

    return val;
}


template<unsigned nBits>
inline void Foam::PackedList<nBits>::setPair(Istream& is)
{
127
    is.readBegin("Tuple2<label,unsigned int>");
128
129
130
131

    const label ind = readLabel(is);
    const unsigned int val = readLabel(is);

132
    is.readEnd("Tuple2<label,unsigned int>");
133
134
135

    if (val > max_value())
    {
136
        FatalIOErrorInFunction(is)
137
138
139
140
141
142
143
144
            << "Out-of-range value " << val << " for PackedList<" << nBits
            << "> at index " << ind
            << ". Maximum permitted value is " << max_value() << "."
            << exit(FatalIOError);
    }

    set(ind, val);

145
    is.check(FUNCTION_NAME);
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
}


template<unsigned nBits>
inline bool Foam::PackedList<nBits>::iteratorBase::writeIfSet(Ostream& os) const
{
    const label val = this->get();

    if (val)
    {
        os  << token::BEGIN_LIST
            << index_ << token::SPACE << val
            << token::END_LIST;

        return true;
    }
162
163

    return false;
164
165
166
}


167
168
// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

169
template<unsigned nBits>
170
inline Foam::PackedList<nBits>::PackedList()
171
:
172
    PackedListCore(),
Mark Olesen's avatar
Mark Olesen committed
173
    StorageList(),
174
175
176
177
    size_(0)
{}


178
template<unsigned nBits>
179
inline Foam::PackedList<nBits>::PackedList(const label size)
180
:
181
    PackedListCore(),
Mark Olesen's avatar
Mark Olesen committed
182
    StorageList(packedLength(size), 0u),
183
184
185
186
    size_(size)
{}


187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
template<unsigned nBits>
inline Foam::PackedList<nBits>::PackedList
(
    const label size,
    const unsigned int val
)
:
    PackedListCore(),
    StorageList(packedLength(size), 0u),
    size_(size)
{
    if (val)
    {
        operator=(val);
    }
}


template<unsigned nBits>
inline Foam::PackedList<nBits>::PackedList(Istream& is)
:
    PackedListCore(),
    StorageList(),
    size_(0)
{
    read(is);
}


216
template<unsigned nBits>
217
218
inline Foam::PackedList<nBits>::PackedList(const PackedList<nBits>& lst)
:
219
    PackedListCore(),
Mark Olesen's avatar
Mark Olesen committed
220
    StorageList(lst),
221
    size_(lst.size_)
222
223
224
{}


225
template<unsigned nBits>
226
227
228
229
230
inline Foam::PackedList<nBits>::PackedList(PackedList<nBits>&& lst)
:
    PackedListCore(),
    StorageList(),
    size_(0)
231
{
232
    transfer(lst);
233
234
235
}


236
template<unsigned nBits>
237
inline Foam::PackedList<nBits>::PackedList(const labelUList& lst)
238
239
240
241
242
:
    PackedListCore(),
    StorageList(packedLength(lst.size()), 0u),
    size_(lst.size())
{
243
244
    const label len = lst.size();
    for (label i = 0; i < len; ++i)
245
246
247
248
249
250
    {
        set(i, lst[i]);
    }
}


251
template<unsigned nBits>
252
inline Foam::PackedList<nBits>::PackedList(const labelUIndList& lst)
253
254
255
256
257
:
    PackedListCore(),
    StorageList(packedLength(lst.size()), 0u),
    size_(lst.size())
{
258
259
    const label len = lst.size();
    for (label i = 0; i < len; ++i)
260
261
262
263
264
265
    {
        set(i, lst[i]);
    }
}


266
template<unsigned nBits>
267
inline Foam::autoPtr<Foam::PackedList<nBits>>
268
Foam::PackedList<nBits>::clone() const
269
{
270
    return autoPtr<PackedList<nBits>>(new PackedList<nBits>(*this));
271
272
273
}


274
275
// * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //

276
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
277
inline Foam::PackedList<nBits>::iteratorBase::iteratorBase()
278
:
279
    list_(nullptr),
280
    index_(0)
Mark Olesen's avatar
Mark Olesen committed
281
282
283
{}


284
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
285
inline Foam::PackedList<nBits>::iteratorBase::iteratorBase
Mark Olesen's avatar
Mark Olesen committed
286
(
Mark Olesen's avatar
Mark Olesen committed
287
288
    const PackedList<nBits>* lst,
    const label i
Mark Olesen's avatar
Mark Olesen committed
289
290
)
:
Mark Olesen's avatar
Mark Olesen committed
291
    list_(const_cast<PackedList<nBits>*>(lst)),
292
    index_(i)
Mark Olesen's avatar
Mark Olesen committed
293
294
295
{}


296
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
297
298
inline unsigned int
Foam::PackedList<nBits>::iteratorBase::get() const
299
{
300
301
302
303
304
    const unsigned int seg = index_ / packing();
    const unsigned int off = index_ % packing();

    const unsigned int& stored = list_->StorageList::operator[](seg);
    return (stored >> (nBits * off)) & max_value();
305
306
307
}


308
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
309
310
inline bool
Foam::PackedList<nBits>::iteratorBase::set(const unsigned int val)
311
{
312
313
314
    const unsigned int seg = index_ / packing();
    const unsigned int off = index_ % packing();

315
316
317
    const unsigned int startBit = nBits * off;
    const unsigned int mask = max_value() << startBit;

318
    unsigned int& stored = list_->StorageList::operator[](seg);
Mark Olesen's avatar
Mark Olesen committed
319
320
    const unsigned int prev = stored;

321
    if (val >= max_value())
Mark Olesen's avatar
Mark Olesen committed
322
    {
323
        // Overflow is max_value, fill everything
324
        stored |= mask;
Mark Olesen's avatar
Mark Olesen committed
325
326
327
    }
    else
    {
328
329
        stored &= ~mask;
        stored |= mask & (val << startBit);
Mark Olesen's avatar
Mark Olesen committed
330
331
    }

Mark Olesen's avatar
Mark Olesen committed
332
    return prev != stored;
333
334
335
}


336
337
338
339
340
341
342
template<unsigned nBits>
inline Foam::label Foam::PackedList<nBits>::iteratorBase::key() const
{
    return index_;
}


343
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
344
345
346
347
348
inline bool Foam::PackedList<nBits>::iteratorBase::operator==
(
    const iteratorBase& iter
) const
{
349
    return this->get() == iter.get();
350
351
352
}


353
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
354
355
356
357
inline bool Foam::PackedList<nBits>::iteratorBase::operator!=
(
    const iteratorBase& iter
) const
Mark Olesen's avatar
Mark Olesen committed
358
{
359
    return this->get() != iter.get();
Mark Olesen's avatar
Mark Olesen committed
360
361
362
}


363
template<unsigned nBits>
364
365
366
367
inline void Foam::PackedList<nBits>::iteratorBase::operator=
(
    const iteratorBase& iter
)
368
{
Mark Olesen's avatar
Mark Olesen committed
369
370
    const unsigned int val = iter.get();
    this->set(val);
371
372
373
}


374
template<unsigned nBits>
375
376
377
378
inline void Foam::PackedList<nBits>::iteratorBase::operator=
(
    const unsigned int val
)
379
{
380
    // Lazy evaluation - increase size on assigment
381
    if (index_ >= list_->size_)
382
    {
383
        list_->resize(index_ + 1);
384
385
    }

Mark Olesen's avatar
Mark Olesen committed
386
    this->set(val);
387
388
389
}


390
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
391
392
inline Foam::PackedList<nBits>::iteratorBase::operator
unsigned int () const
393
{
394
    // Lazy evaluation - return 0 for out-of-range
395
    if (index_ >= list_->size_)
396
    {
Mark Olesen's avatar
Mark Olesen committed
397
        return 0;
398
    }
Mark Olesen's avatar
Mark Olesen committed
399
400
401
402
403

    return this->get();
}


404
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
405
406
407
408
409
410
inline Foam::PackedList<nBits>::iterator::iterator()
:
    iteratorBase()
{}


411
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
412
413
414
415
416
inline Foam::PackedList<nBits>::const_iterator::const_iterator()
:
    iteratorBase()
{}

417

418
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
419
420
421
422
423
424
425
inline Foam::PackedList<nBits>::iterator::iterator
(
    const iteratorBase& iter
)
:
    iteratorBase(iter)
{
426
    // Avoid going past end()
427
428
429
430
431
    // eg, iter = iterator(list, Inf)
    if (this->index_ > this->list_->size_)
    {
        this->index_ = this->list_->size_;
    }
Mark Olesen's avatar
Mark Olesen committed
432
433
434
}


435
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
436
437
438
439
440
441
442
inline Foam::PackedList<nBits>::const_iterator::const_iterator
(
    const iteratorBase& iter
)
:
    iteratorBase(iter)
{
443
    // Avoid going past end()
444
445
446
447
448
    // eg, iter = iterator(list, Inf)
    if (this->index_ > this->list_->size_)
    {
        this->index_ = this->list_->size_;
    }
Mark Olesen's avatar
Mark Olesen committed
449
450
451
}


452
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
453
454
455
456
457
458
459
460
461
462
inline Foam::PackedList<nBits>::iterator::iterator
(
    const PackedList<nBits>* lst,
    const label i
)
:
    iteratorBase(lst, i)
{}


463
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
464
465
466
467
468
469
470
471
472
473
inline Foam::PackedList<nBits>::const_iterator::const_iterator
(
    const PackedList<nBits>* lst,
    const label i
)
:
    iteratorBase(lst, i)
{}


474
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
475
476
477
478
479
480
481
482
483
inline Foam::PackedList<nBits>::const_iterator::const_iterator
(
    const iterator& iter
)
:
    iteratorBase(static_cast<const iteratorBase&>(iter))
{}


484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
template<unsigned nBits>
inline bool Foam::PackedList<nBits>::iterator::operator==
(
    const iteratorBase& iter
) const
{
    return this->index_ == iter.index_;
}


template<unsigned nBits>
inline bool Foam::PackedList<nBits>::iterator::operator!=
(
    const iteratorBase& iter
) const
{
    return this->index_ != iter.index_;
}


template<unsigned nBits>
inline bool Foam::PackedList<nBits>::const_iterator::operator==
(
    const iteratorBase& iter
) const
{
    return this->index_ == iter.index_;
}


template<unsigned nBits>
inline bool Foam::PackedList<nBits>::const_iterator::operator!=
(
    const iteratorBase& iter
) const
{
    return this->index_ != iter.index_;
}


524
template<unsigned nBits>
525
526
527
528
inline void Foam::PackedList<nBits>::iterator::operator=
(
    const iteratorBase& iter
)
Mark Olesen's avatar
Mark Olesen committed
529
{
530
531
532
    this->list_  = iter.list_;
    this->index_ = iter.index_;

533
    // Avoid going past end()
534
535
536
537
538
    // eg, iter = iterator(list, Inf)
    if (this->index_ > this->list_->size_)
    {
        this->index_ = this->list_->size_;
    }
539
540
541
}


542
template<unsigned nBits>
543
544
545
546
inline void Foam::PackedList<nBits>::const_iterator::operator=
(
    const iteratorBase& iter
)
547
{
548
549
550
    this->list_  = iter.list_;
    this->index_ = iter.index_;

551
    // Avoid going past end()
552
553
554
555
556
557
    // eg, iter = iterator(list, Inf)
    if (this->index_ > this->list_->size_)
    {
        this->index_ = this->list_->size_;
    }

Mark Olesen's avatar
Mark Olesen committed
558
559
560
561
    return *this;
}


562
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
563
564
565
inline typename Foam::PackedList<nBits>::iterator&
Foam::PackedList<nBits>::iterator::operator++()
{
566
    ++this->index_;
Mark Olesen's avatar
Mark Olesen committed
567
568
569
570
    return *this;
}


571
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
572
573
574
inline typename Foam::PackedList<nBits>::const_iterator&
Foam::PackedList<nBits>::const_iterator::operator++()
{
575
    ++this->index_;
Mark Olesen's avatar
Mark Olesen committed
576
    return *this;
577
578
579
}


580
template<unsigned nBits>
581
inline typename Foam::PackedList<nBits>::iterator
Mark Olesen's avatar
Mark Olesen committed
582
Foam::PackedList<nBits>::iterator::operator++(int)
583
584
{
    iterator old = *this;
585
    ++this->index_;
586
587
588
589
    return old;
}


590
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
591
592
inline typename Foam::PackedList<nBits>::const_iterator
Foam::PackedList<nBits>::const_iterator::operator++(int)
Mark Olesen's avatar
Mark Olesen committed
593
{
Mark Olesen's avatar
Mark Olesen committed
594
    const_iterator old = *this;
595
    ++this->index_;
Mark Olesen's avatar
Mark Olesen committed
596
    return old;
Mark Olesen's avatar
Mark Olesen committed
597
598
599
}


600
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
601
602
inline typename Foam::PackedList<nBits>::iterator&
Foam::PackedList<nBits>::iterator::operator--()
603
{
604
    --this->index_;
Mark Olesen's avatar
Mark Olesen committed
605
    return *this;
606
607
608
}


609
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
610
611
inline typename Foam::PackedList<nBits>::const_iterator&
Foam::PackedList<nBits>::const_iterator::operator--()
Mark Olesen's avatar
Mark Olesen committed
612
{
613
    --this->index_;
Mark Olesen's avatar
Mark Olesen committed
614
    return *this;
Mark Olesen's avatar
Mark Olesen committed
615
616
617
}


618
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
619
620
inline typename Foam::PackedList<nBits>::iterator
Foam::PackedList<nBits>::iterator::operator--(int)
Mark Olesen's avatar
Mark Olesen committed
621
{
Mark Olesen's avatar
Mark Olesen committed
622
    iterator old = *this;
623
    --this->index_;
Mark Olesen's avatar
Mark Olesen committed
624
    return old;
Mark Olesen's avatar
Mark Olesen committed
625
626
627
}


628
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
629
630
inline typename Foam::PackedList<nBits>::const_iterator
Foam::PackedList<nBits>::const_iterator::operator--(int)
Mark Olesen's avatar
Mark Olesen committed
631
{
Mark Olesen's avatar
Mark Olesen committed
632
    const_iterator old = *this;
633
    --this->index_;
Mark Olesen's avatar
Mark Olesen committed
634
    return old;
Mark Olesen's avatar
Mark Olesen committed
635
636
637
}


638
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
639
640
inline typename Foam::PackedList<nBits>::iteratorBase&
Foam::PackedList<nBits>::iterator::operator*()
Mark Olesen's avatar
Mark Olesen committed
641
{
Mark Olesen's avatar
Mark Olesen committed
642
    return static_cast<iteratorBase&>(*this);
Mark Olesen's avatar
Mark Olesen committed
643
644
645
}


646
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
647
648
649
650
651
inline typename Foam::PackedList<nBits>::iteratorBase&
Foam::PackedList<nBits>::iterator::operator()()
{
    return static_cast<iteratorBase&>(*this);
}
Mark Olesen's avatar
Mark Olesen committed
652
653


654
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
655
656
inline unsigned int
Foam::PackedList<nBits>::const_iterator::operator*() const
657
{
Mark Olesen's avatar
Mark Olesen committed
658
    return this->get();
659
660
661
}


662
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
663
664
inline unsigned int
Foam::PackedList<nBits>::const_iterator::operator()() const
665
{
Mark Olesen's avatar
Mark Olesen committed
666
    return this->get();
667
668
669
}


670
template<unsigned nBits>
671
672
673
inline typename Foam::PackedList<nBits>::iterator
Foam::PackedList<nBits>::begin()
{
Mark Olesen's avatar
Mark Olesen committed
674
    return iterator(this, 0);
675
676
677
}


678
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
679
680
681
inline typename Foam::PackedList<nBits>::const_iterator
Foam::PackedList<nBits>::begin() const
{
Mark Olesen's avatar
Mark Olesen committed
682
    return const_iterator(this, 0);
Mark Olesen's avatar
Mark Olesen committed
683
684
685
}


686
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
687
688
689
inline typename Foam::PackedList<nBits>::const_iterator
Foam::PackedList<nBits>::cbegin() const
{
Mark Olesen's avatar
Mark Olesen committed
690
    return const_iterator(this, 0);
Mark Olesen's avatar
Mark Olesen committed
691
692
693
}


694
template<unsigned nBits>
695
696
697
inline typename Foam::PackedList<nBits>::iterator
Foam::PackedList<nBits>::end()
{
698
    return iterator(this, size_);
699
700
701
}


702
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
703
704
705
inline typename Foam::PackedList<nBits>::const_iterator
Foam::PackedList<nBits>::end() const
{
706
    return const_iterator(this, size_);
Mark Olesen's avatar
Mark Olesen committed
707
708
709
}


710
template<unsigned nBits>
Mark Olesen's avatar
Mark Olesen committed
711
712
713
inline typename Foam::PackedList<nBits>::const_iterator
Foam::PackedList<nBits>::cend() const
{
714
    return const_iterator(this, size_);
Mark Olesen's avatar
Mark Olesen committed
715
716
717
}


718
719
// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //

720
template<unsigned nBits>
721
722
723
724
725
726
inline Foam::label Foam::PackedList<nBits>::size() const
{
    return size_;
}


727
template<unsigned nBits>
728
inline bool Foam::PackedList<nBits>::empty() const
729
{
730
    return !size_;
731
732
733
}


734
template<unsigned nBits>
735
736
inline void Foam::PackedList<nBits>::resize
(
737
    const label newSize,
738
    const unsigned int val
739
)
740
{
741
742
743
744
    reserve(newSize);

    const label oldSize = size_;
    size_ = newSize;
Mark Olesen's avatar
Mark Olesen committed
745

746
    if (size_ > oldSize)
Mark Olesen's avatar
Mark Olesen committed
747
    {
748
        // Fill new elements or newly exposed elements
749
        if (val)
Mark Olesen's avatar
Mark Olesen committed
750
        {
751
            // Fill value for complete segments
Mark Olesen's avatar
Mark Olesen committed
752
            unsigned int fill = val;
753

754
            if (val >= max_value())
Mark Olesen's avatar
Mark Olesen committed
755
            {
756
                // Fill everything
757
                fill = maskLower(packing());
Mark Olesen's avatar
Mark Olesen committed
758
            }
759
            else
Mark Olesen's avatar
Mark Olesen committed
760
            {
761
762
763
764
                for (unsigned int i = 1; i < packing(); ++i)
                {
                    fill |= (fill << nBits);
                }
Mark Olesen's avatar
Mark Olesen committed
765
766
            }

767
            // Fill in complete segments
768
769
770
            const label oldLen = packedLength(oldSize);
            const label newLen = packedLength(size_);
            for (label i=oldLen; i < newLen; ++i)
Mark Olesen's avatar
Mark Olesen committed
771
            {
772
773
                StorageList::operator[](i) = fill;
            }
Mark Olesen's avatar
Mark Olesen committed
774

775
            // Finish previous partial segment, preserve existing value
776
777
778
779
780
781
            {
                const unsigned int off = oldSize % packing();
                if (off)
                {
                    const unsigned int seg = oldSize / packing();
                    const unsigned int mask = maskLower(off);
Mark Olesen's avatar
Mark Olesen committed
782

783
784
785
                    StorageList::operator[](seg) &= mask;
                    StorageList::operator[](seg) |= ~mask & fill;
                }
Mark Olesen's avatar
Mark Olesen committed
786
787
            }

788

789
            // Mask off the (new) final partial segment
Mark Olesen's avatar
Mark Olesen committed
790
            {
791
792
793
794
795
796
797
                const unsigned int off = size_ % packing();
                if (off)
                {
                    const unsigned int seg = size_ / packing();

                    StorageList::operator[](seg) &= maskLower(off);
                }
Mark Olesen's avatar
Mark Olesen committed
798
799
            }
        }
800
801
802
    }
    else if (size_ < oldSize)
    {
803
        // Resize shrinking
804
805
        // - clear newly exposed elements

806
        // Fill in complete segments
807
808
809
        const label oldLen = packedLength(oldSize);
        const label newLen = packedLength(size_);
        for (label i=newLen; i < oldLen; ++i)
Mark Olesen's avatar
Mark Olesen committed
810
        {
811
            StorageList::operator[](i) = 0u;
Mark Olesen's avatar
Mark Olesen committed
812
813
        }

814
        // Mask off the final partial segment
815
816
817
818
819
820
821
822
823
824
        {
            const unsigned int off = size_ % packing();
            if (off)
            {
                const unsigned int seg = size_ / packing();

                StorageList::operator[](seg) &= maskLower(off);
            }
        }
    }
825
826
827
}


828
template<unsigned nBits>
829
830
831
inline void Foam::PackedList<nBits>::setSize
(
    const label newSize,
832
    const unsigned int val
833
834
835
)
{
    resize(newSize, val);
836
837
838
}


839
template<unsigned nBits>
840
841
inline Foam::label Foam::PackedList<nBits>::capacity() const
{
Mark Olesen's avatar
Mark Olesen committed
842
    return packing() * StorageList::size();
843
844
845
}


846
template<unsigned nBits>
847
inline void Foam::PackedList<nBits>::setCapacity(const label nElem)
848
{
Mark Olesen's avatar
Mark Olesen committed
849
    StorageList::setSize(packedLength(nElem), 0u);
850

851
    // Truncate addressed size too
852
    if (size_ > nElem)
853
    {
854
        size_ = nElem;
855

856
        // Mask off the final partial segment
857
858
859
860
861
862
863
        const unsigned int off = size_ % packing();
        if (off)
        {
            const unsigned int seg = size_ / packing();

            StorageList::operator[](seg) &= maskLower(off);
        }
864
    }
865
866
867
}


868
template<unsigned nBits>
869
inline void Foam::PackedList<nBits>::reserve(const label nElem)
870
{
871
    const label len = packedLength(nElem);
872

873
    // Allocate more capacity if necessary
Mark Olesen's avatar
Mark Olesen committed
874
    if (len > StorageList::size())
875
    {
876
877
878
879
880
        StorageList::setSize
        (
            max
            (
                len,
881
882
                // SizeInc=0, SizeMult=2, SizeDiv=1
                2 * StorageList::size()
883
884
885
            ),
            0u
        );
886
887
888
889
    }
}


890
891
892
893
894
895
896
template<unsigned nBits>
inline void Foam::PackedList<nBits>::reset()
{
    StorageList::operator=(0u);
}


897
template<unsigned nBits>
898
899
inline void Foam::PackedList<nBits>::clear()
{
900
    reset();
901
902
903
904
    size_ = 0;
}


905
template<unsigned nBits>
906
907
inline void Foam::PackedList<nBits>::clearStorage()
{
Mark Olesen's avatar
Mark Olesen committed
908
    StorageList::clear();
909
910
911
912
    size_ = 0;
}


913
template<unsigned nBits>
914
915
inline void Foam::PackedList<nBits>::shrink()
{
916
    // Any uneed space allocated?
917
    const label len = packedLength();
Mark Olesen's avatar
Mark Olesen committed
918
    if (len < StorageList::size())
919
    {
Mark Olesen's avatar
Mark Olesen committed
920
        StorageList::setSize(len);
921
    }
922
923
}

924

925
template<unsigned nBits>
Andrew Heather's avatar
Andrew Heather committed
926
inline Foam::List<unsigned int>& Foam::PackedList<nBits>::storage()
927
928
929
930
931
{
    return static_cast<StorageList&>(*this);
}


932
template<unsigned nBits>
Andrew Heather's avatar
Andrew Heather committed
933
inline const Foam::List<unsigned int>& Foam::PackedList<nBits>::storage() const
934
{
Mark Olesen's avatar
Mark Olesen committed
935
    return static_cast<const StorageList&>(*this);
936
}
937

938

939
940
941
942
943
944
945
946
template<unsigned nBits>
inline Foam::label Foam::PackedList<nBits>::packedLength() const
{
    return packedLength(size_);
}


template<unsigned nBits>
947
inline std::streamsize Foam::PackedList<nBits>::byteSize() const
948
949
950
951
952
{
    return packedLength() * sizeof(StorageType);
}


953
template<unsigned nBits>
954
955
956
957
inline void Foam::PackedList<nBits>::transfer(PackedList<nBits>& lst)
{
    size_ = lst.size_;
    lst.size_ = 0;
958

Mark Olesen's avatar
Mark Olesen committed
959
    StorageList::transfer(lst);
960
961
962
}


963
template<unsigned nBits>
964
inline unsigned int Foam::PackedList<nBits>::get(const label i) const
965
{
966
    // Lazy evaluation - return 0 for out-of-range
967
    if (i < 0 || i >= size_)
968
    {
969
        return 0u;
970
    }
971
972

    return iteratorBase(this, i).get();
973
974
975
}


976
template<unsigned nBits>
977
inline unsigned int Foam::PackedList<nBits>::operator[](const label i) const
mattijs's avatar
mattijs committed
978
{
979
    return get(i);
mattijs's avatar
mattijs committed
980
981
982
}


983
template<unsigned nBits>
984
985
986
987
988
inline bool Foam::PackedList<nBits>::set
(
    const label i,
    const unsigned int val
)
989
{
990
    if (i < 0)
991
    {
992
        // Lazy evaluation - ignore out-of-bounds
993
        return false;