Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <OpenFOAM/error.H>
00028 #include <climits>
00029
00030
00031
00032 template<unsigned nBits>
00033 inline unsigned int Foam::PackedList<nBits>::max_bits()
00034 {
00035 return sizeof(StorageType)*CHAR_BIT - 1;
00036 }
00037
00038
00039 template<unsigned nBits>
00040 inline unsigned int Foam::PackedList<nBits>::max_value()
00041 {
00042 return (1u << nBits) - 1;
00043 }
00044
00045
00046 template<unsigned nBits>
00047 inline unsigned int Foam::PackedList<nBits>::packing()
00048 {
00049 return sizeof(StorageType)*CHAR_BIT / nBits;
00050 }
00051
00052
00053 template<unsigned nBits>
00054 inline unsigned int Foam::PackedList<nBits>::maskLower(unsigned offset)
00055 {
00056
00057
00058
00059 return (~0u >> ( sizeof(StorageType)*CHAR_BIT - nBits * offset));
00060 }
00061
00062
00063 template<unsigned nBits>
00064 inline Foam::label Foam::PackedList<nBits>::packedLength(const label nElem)
00065 {
00066 return (nElem + packing() - 1) / packing();
00067 }
00068
00069
00070
00071
00072 template<unsigned nBits>
00073 inline Foam::PackedList<nBits>::PackedList()
00074 :
00075 StorageList(),
00076 size_(0)
00077 {}
00078
00079
00080 template<unsigned nBits>
00081 inline Foam::PackedList<nBits>::PackedList(const label size)
00082 :
00083 StorageList(packedLength(size), 0u),
00084 size_(size)
00085 {}
00086
00087
00088 template<unsigned nBits>
00089 inline Foam::PackedList<nBits>::PackedList(const PackedList<nBits>& lst)
00090 :
00091 StorageList(lst),
00092 size_(lst.size_)
00093 {}
00094
00095
00096 template<unsigned nBits>
00097 inline Foam::PackedList<nBits>::PackedList(const Xfer<PackedList<nBits> >& lst)
00098 {
00099 transfer(lst());
00100 }
00101
00102
00103 template<unsigned nBits>
00104 inline Foam::autoPtr<Foam::PackedList<nBits> >
00105 Foam::PackedList<nBits>::clone() const
00106 {
00107 return autoPtr<PackedList<nBits> >(new PackedList<nBits>(*this));
00108 }
00109
00110
00111
00112
00113
00114
00115 template<unsigned nBits>
00116 inline Foam::PackedList<nBits>::iteratorBase::iteratorBase()
00117 :
00118 list_(0),
00119 index_(0)
00120 {}
00121
00122
00123 template<unsigned nBits>
00124 inline Foam::PackedList<nBits>::iteratorBase::iteratorBase
00125 (
00126 const PackedList<nBits>* lst,
00127 const label i
00128 )
00129 :
00130 list_(const_cast<PackedList<nBits>*>(lst)),
00131 index_(i)
00132 {}
00133
00134
00135 template<unsigned nBits>
00136 inline unsigned int
00137 Foam::PackedList<nBits>::iteratorBase::get() const
00138 {
00139 const unsigned int seg = index_ / packing();
00140 const unsigned int off = index_ % packing();
00141
00142 const unsigned int& stored = list_->StorageList::operator[](seg);
00143 return (stored >> (nBits * off)) & max_value();
00144 }
00145
00146
00147 template<unsigned nBits>
00148 inline bool
00149 Foam::PackedList<nBits>::iteratorBase::set(const unsigned int val)
00150 {
00151 const unsigned int seg = index_ / packing();
00152 const unsigned int off = index_ % packing();
00153
00154 unsigned int& stored = list_->StorageList::operator[](seg);
00155 const unsigned int prev = stored;
00156
00157 const unsigned int startBit = nBits * off;
00158 const unsigned int maskNew = max_value() << startBit;
00159
00160 if (val & ~max_value())
00161 {
00162
00163 stored |= maskNew;
00164 }
00165 else
00166 {
00167 stored &= ~maskNew;
00168 stored |= maskNew & (val << startBit);
00169 }
00170
00171 return prev != stored;
00172 }
00173
00174
00175 template<unsigned nBits>
00176 inline bool Foam::PackedList<nBits>::iteratorBase::operator==
00177 (
00178 const iteratorBase& iter
00179 ) const
00180 {
00181 return this->get() == iter.get();
00182 }
00183
00184
00185 template<unsigned nBits>
00186 inline bool Foam::PackedList<nBits>::iteratorBase::operator!=
00187 (
00188 const iteratorBase& iter
00189 ) const
00190 {
00191 return this->get() != iter.get();
00192 }
00193
00194
00195 template<unsigned nBits>
00196 inline unsigned int
00197 Foam::PackedList<nBits>::iteratorBase::operator=(const iteratorBase& iter)
00198 {
00199 const unsigned int val = iter.get();
00200 this->set(val);
00201 return val;
00202 }
00203
00204
00205 template<unsigned nBits>
00206 inline unsigned int
00207 Foam::PackedList<nBits>::iteratorBase::operator=(const unsigned int val)
00208 {
00209
00210 if (index_ >= list_->size_)
00211 {
00212 list_->resize(index_ + 1);
00213 }
00214
00215 this->set(val);
00216 return val;
00217 }
00218
00219
00220 template<unsigned nBits>
00221 inline Foam::PackedList<nBits>::iteratorBase::operator
00222 unsigned int () const
00223 {
00224
00225 if (index_ >= list_->size_)
00226 {
00227 return 0;
00228 }
00229
00230 return this->get();
00231 }
00232
00233
00234
00235
00236 template<unsigned nBits>
00237 inline Foam::PackedList<nBits>::iterator::iterator()
00238 :
00239 iteratorBase()
00240 {}
00241
00242
00243 template<unsigned nBits>
00244 inline Foam::PackedList<nBits>::const_iterator::const_iterator()
00245 :
00246 iteratorBase()
00247 {}
00248
00249
00250 template<unsigned nBits>
00251 inline Foam::PackedList<nBits>::iterator::iterator
00252 (
00253 const iteratorBase& iter
00254 )
00255 :
00256 iteratorBase(iter)
00257 {
00258
00259
00260 if (this->index_ > this->list_->size_)
00261 {
00262 this->index_ = this->list_->size_;
00263 }
00264 }
00265
00266
00267 template<unsigned nBits>
00268 inline Foam::PackedList<nBits>::const_iterator::const_iterator
00269 (
00270 const iteratorBase& iter
00271 )
00272 :
00273 iteratorBase(iter)
00274 {
00275
00276
00277 if (this->index_ > this->list_->size_)
00278 {
00279 this->index_ = this->list_->size_;
00280 }
00281 }
00282
00283
00284 template<unsigned nBits>
00285 inline Foam::PackedList<nBits>::iterator::iterator
00286 (
00287 const PackedList<nBits>* lst,
00288 const label i
00289 )
00290 :
00291 iteratorBase(lst, i)
00292 {}
00293
00294
00295 template<unsigned nBits>
00296 inline Foam::PackedList<nBits>::const_iterator::const_iterator
00297 (
00298 const PackedList<nBits>* lst,
00299 const label i
00300 )
00301 :
00302 iteratorBase(lst, i)
00303 {}
00304
00305
00306 template<unsigned nBits>
00307 inline Foam::PackedList<nBits>::const_iterator::const_iterator
00308 (
00309 const iterator& iter
00310 )
00311 :
00312 iteratorBase(static_cast<const iteratorBase&>(iter))
00313 {}
00314
00315
00316 template<unsigned nBits>
00317 inline bool Foam::PackedList<nBits>::iterator::operator==
00318 (
00319 const iteratorBase& iter
00320 ) const
00321 {
00322 return this->index_ == iter.index_;
00323 }
00324
00325
00326 template<unsigned nBits>
00327 inline bool Foam::PackedList<nBits>::iterator::operator!=
00328 (
00329 const iteratorBase& iter
00330 ) const
00331 {
00332 return this->index_ != iter.index_;
00333 }
00334
00335
00336
00337 template<unsigned nBits>
00338 inline bool Foam::PackedList<nBits>::const_iterator::operator==
00339 (
00340 const iteratorBase& iter
00341 ) const
00342 {
00343 return this->index_ == iter.index_;
00344 }
00345
00346
00347 template<unsigned nBits>
00348 inline bool Foam::PackedList<nBits>::const_iterator::operator!=
00349 (
00350 const iteratorBase& iter
00351 ) const
00352 {
00353 return this->index_ != iter.index_;
00354 }
00355
00356
00357
00358 template<unsigned nBits>
00359 inline typename Foam::PackedList<nBits>::iterator&
00360 Foam::PackedList<nBits>::iterator::operator=(const iteratorBase& iter)
00361 {
00362 this->list_ = iter.list_;
00363 this->index_ = iter.index_;
00364
00365
00366
00367 if (this->index_ > this->list_->size_)
00368 {
00369 this->index_ = this->list_->size_;
00370 }
00371
00372 return *this;
00373 }
00374
00375
00376 template<unsigned nBits>
00377 inline typename Foam::PackedList<nBits>::const_iterator&
00378 Foam::PackedList<nBits>::const_iterator::operator=(const iteratorBase& iter)
00379 {
00380 this->list_ = iter.list_;
00381 this->index_ = iter.index_;
00382
00383
00384
00385 if (this->index_ > this->list_->size_)
00386 {
00387 this->index_ = this->list_->size_;
00388 }
00389
00390 return *this;
00391 }
00392
00393
00394 template<unsigned nBits>
00395 inline typename Foam::PackedList<nBits>::iterator&
00396 Foam::PackedList<nBits>::iterator::operator++()
00397 {
00398 ++this->index_;
00399 return *this;
00400 }
00401
00402
00403 template<unsigned nBits>
00404 inline typename Foam::PackedList<nBits>::const_iterator&
00405 Foam::PackedList<nBits>::const_iterator::operator++()
00406 {
00407 ++this->index_;
00408 return *this;
00409 }
00410
00411
00412 template<unsigned nBits>
00413 inline typename Foam::PackedList<nBits>::iterator
00414 Foam::PackedList<nBits>::iterator::operator++(int)
00415 {
00416 iterator old = *this;
00417 ++this->index_;
00418 return old;
00419 }
00420
00421
00422 template<unsigned nBits>
00423 inline typename Foam::PackedList<nBits>::const_iterator
00424 Foam::PackedList<nBits>::const_iterator::operator++(int)
00425 {
00426 const_iterator old = *this;
00427 ++this->index_;
00428 return old;
00429 }
00430
00431
00432 template<unsigned nBits>
00433 inline typename Foam::PackedList<nBits>::iterator&
00434 Foam::PackedList<nBits>::iterator::operator--()
00435 {
00436 --this->index_;
00437 return *this;
00438 }
00439
00440
00441 template<unsigned nBits>
00442 inline typename Foam::PackedList<nBits>::const_iterator&
00443 Foam::PackedList<nBits>::const_iterator::operator--()
00444 {
00445 --this->index_;
00446 return *this;
00447 }
00448
00449
00450 template<unsigned nBits>
00451 inline typename Foam::PackedList<nBits>::iterator
00452 Foam::PackedList<nBits>::iterator::operator--(int)
00453 {
00454 iterator old = *this;
00455 --this->index_;
00456 return old;
00457 }
00458
00459
00460 template<unsigned nBits>
00461 inline typename Foam::PackedList<nBits>::const_iterator
00462 Foam::PackedList<nBits>::const_iterator::operator--(int)
00463 {
00464 const_iterator old = *this;
00465 --this->index_;
00466 return old;
00467 }
00468
00469
00470 template<unsigned nBits>
00471 inline typename Foam::PackedList<nBits>::iteratorBase&
00472 Foam::PackedList<nBits>::iterator::operator*()
00473 {
00474 return static_cast<iteratorBase&>(*this);
00475 }
00476
00477
00478 template<unsigned nBits>
00479 inline typename Foam::PackedList<nBits>::iteratorBase&
00480 Foam::PackedList<nBits>::iterator::operator()()
00481 {
00482 return static_cast<iteratorBase&>(*this);
00483 }
00484
00485
00486 template<unsigned nBits>
00487 inline unsigned int
00488 Foam::PackedList<nBits>::const_iterator::operator*() const
00489 {
00490 return this->get();
00491 }
00492
00493
00494 template<unsigned nBits>
00495 inline unsigned int
00496 Foam::PackedList<nBits>::const_iterator::operator()() const
00497 {
00498 return this->get();
00499 }
00500
00501
00502 template<unsigned nBits>
00503 inline typename Foam::PackedList<nBits>::iterator
00504 Foam::PackedList<nBits>::begin()
00505 {
00506 return iterator(this, 0);
00507 }
00508
00509
00510 template<unsigned nBits>
00511 inline typename Foam::PackedList<nBits>::const_iterator
00512 Foam::PackedList<nBits>::begin() const
00513 {
00514 return const_iterator(this, 0);
00515 }
00516
00517
00518 template<unsigned nBits>
00519 inline typename Foam::PackedList<nBits>::const_iterator
00520 Foam::PackedList<nBits>::cbegin() const
00521 {
00522 return const_iterator(this, 0);
00523 }
00524
00525
00526 template<unsigned nBits>
00527 inline typename Foam::PackedList<nBits>::iterator
00528 Foam::PackedList<nBits>::end()
00529 {
00530 return iterator(this, size_);
00531 }
00532
00533
00534 template<unsigned nBits>
00535 inline typename Foam::PackedList<nBits>::const_iterator
00536 Foam::PackedList<nBits>::end() const
00537 {
00538 return const_iterator(this, size_);
00539 }
00540
00541
00542 template<unsigned nBits>
00543 inline typename Foam::PackedList<nBits>::const_iterator
00544 Foam::PackedList<nBits>::cend() const
00545 {
00546 return const_iterator(this, size_);
00547 }
00548
00549
00550
00551
00552 template<unsigned nBits>
00553 inline Foam::label Foam::PackedList<nBits>::size() const
00554 {
00555 return size_;
00556 }
00557
00558
00559 template<unsigned nBits>
00560 inline bool Foam::PackedList<nBits>::empty() const
00561 {
00562 return !size_;
00563 }
00564
00565
00566 template<unsigned nBits>
00567 inline void Foam::PackedList<nBits>::resize
00568 (
00569 const label nElem,
00570 const unsigned int& val
00571 )
00572 {
00573 reserve(nElem);
00574
00575 if (nElem > size_)
00576 {
00577
00578 if (size_)
00579 {
00580
00581 unsigned int fill = val;
00582
00583 if (fill & ~max_value())
00584 {
00585
00586 fill = ~0u;
00587 }
00588 else
00589 {
00590 for (unsigned int i = 1; i < packing(); ++i)
00591 {
00592 fill |= (fill << nBits);
00593 }
00594 }
00595
00596 unsigned int seg = size_ / packing();
00597 unsigned int off = size_ % packing();
00598
00599
00600 if (off)
00601 {
00602 unsigned int maskOld = maskLower(off);
00603
00604 StorageList::operator[](seg) &= maskOld;
00605 StorageList::operator[](seg) |= ~maskOld & fill;
00606
00607
00608 seg++;
00609 }
00610
00611 unsigned int endSeg = nElem / packing();
00612
00613 while (seg < endSeg)
00614 {
00615 StorageList::operator[](seg++) = fill;
00616 }
00617 }
00618 else
00619 {
00620
00621 operator=(val);
00622 }
00623 }
00624
00625 size_ = nElem;
00626 }
00627
00628
00629 template<unsigned nBits>
00630 inline void Foam::PackedList<nBits>::setSize
00631 (
00632 const label newSize,
00633 const unsigned int& val
00634 )
00635 {
00636 resize(newSize, val);
00637 }
00638
00639
00640
00641 template<unsigned nBits>
00642 inline Foam::label Foam::PackedList<nBits>::capacity() const
00643 {
00644 return packing() * StorageList::size();
00645 }
00646
00647
00648 template<unsigned nBits>
00649 inline void Foam::PackedList<nBits>::setCapacity(const label nElem)
00650 {
00651 StorageList::setSize(packedLength(nElem), 0u);
00652
00653
00654 if (size_ > nElem)
00655 {
00656 size_ = nElem;
00657 }
00658 }
00659
00660
00661 template<unsigned nBits>
00662 inline void Foam::PackedList<nBits>::reserve
00663 (
00664 const label nElem
00665 )
00666 {
00667 label len = packedLength(nElem);
00668
00669
00670 if (len > StorageList::size())
00671 {
00672
00673 StorageList::setSize
00674 (
00675 max
00676 (
00677 len,
00678 StorageList::size()*2
00679 ),
00680 0u
00681 );
00682 }
00683 }
00684
00685
00686 template<unsigned nBits>
00687 inline void Foam::PackedList<nBits>::clear()
00688 {
00689 size_ = 0;
00690 }
00691
00692
00693 template<unsigned nBits>
00694 inline void Foam::PackedList<nBits>::clearStorage()
00695 {
00696 StorageList::clear();
00697 size_ = 0;
00698 }
00699
00700
00701 template<unsigned nBits>
00702 inline void Foam::PackedList<nBits>::shrink()
00703 {
00704 label len = packedLength(size_);
00705
00706
00707 if (len < StorageList::size())
00708 {
00709 StorageList::setSize(len);
00710 }
00711 }
00712
00713 template<unsigned nBits>
00714 inline Foam::List<unsigned int>&
00715 Foam::PackedList<nBits>::storage()
00716 {
00717 return static_cast<StorageList&>(*this);
00718 }
00719
00720
00721 template<unsigned nBits>
00722 inline const Foam::List<unsigned int>&
00723 Foam::PackedList<nBits>::storage() const
00724 {
00725 return static_cast<const StorageList&>(*this);
00726 }
00727
00728
00729 template<unsigned nBits>
00730 inline void Foam::PackedList<nBits>::transfer(PackedList<nBits>& lst)
00731 {
00732 size_ = lst.size_;
00733 lst.size_ = 0;
00734
00735 StorageList::transfer(lst);
00736 }
00737
00738
00739 template<unsigned nBits>
00740 inline Foam::Xfer< Foam::PackedList<nBits> >
00741 Foam::PackedList<nBits>::xfer()
00742 {
00743 return xferMove(*this);
00744 }
00745
00746
00747 template<unsigned nBits>
00748 inline unsigned int Foam::PackedList<nBits>::get(const label i) const
00749 {
00750 # ifdef FULLDEBUG
00751 if (i < 0)
00752 {
00753 FatalErrorIn("PackedList<nBits>::get(const label)")
00754 << "negative index " << i << " max=" << size_-1
00755 << abort(FatalError);
00756 }
00757 # endif
00758
00759
00760 if (i < size_)
00761 {
00762 return iteratorBase(this, i).get();
00763 }
00764 else
00765 {
00766 return 0;
00767 }
00768 }
00769
00770
00771 template<unsigned nBits>
00772 inline unsigned int Foam::PackedList<nBits>::operator[](const label i) const
00773 {
00774
00775 if (i < size_)
00776 {
00777 return iteratorBase(this, i).get();
00778 }
00779 else
00780 {
00781 return 0;
00782 }
00783 }
00784
00785
00786 template<unsigned nBits>
00787 inline bool Foam::PackedList<nBits>::set
00788 (
00789 const label i,
00790 const unsigned int val
00791 )
00792 {
00793 # ifdef FULLDEBUG
00794 if (i < 0)
00795 {
00796 FatalErrorIn("PackedList<nBits>::set(const label)")
00797 << "negative index " << i << " max=" << size_-1
00798 << abort(FatalError);
00799 }
00800 # endif
00801
00802
00803 if (i >= size_)
00804 {
00805 resize(i + 1);
00806 }
00807
00808 return iteratorBase(this, i).set(val);
00809 }
00810
00811
00812 template<unsigned nBits>
00813 inline bool Foam::PackedList<nBits>::unset(const label i)
00814 {
00815
00816 if (i < 0 || i >= size_)
00817 {
00818 return false;
00819 }
00820
00821 return iteratorBase(this, i).set(0u);
00822 }
00823
00824
00825 template<unsigned nBits>
00826 inline void Foam::PackedList<nBits>::append(const unsigned int val)
00827 {
00828 label elemI = size_;
00829 reserve(elemI + 1);
00830 size_++;
00831
00832 iteratorBase(this, elemI).set(val);
00833 }
00834
00835
00836 template<unsigned nBits>
00837 inline unsigned int Foam::PackedList<nBits>::remove()
00838 {
00839 if (!size_)
00840 {
00841 FatalErrorIn
00842 (
00843 "Foam::PackedList<nBits>::remove()"
00844 ) << "List is empty" << abort(FatalError);
00845 }
00846
00847 label elemI = size_ - 1;
00848 const unsigned int val = iteratorBase(this, elemI).get();
00849 resize(elemI);
00850
00851 return val;
00852 }
00853
00854
00855 template<unsigned nBits>
00856 inline typename Foam::PackedList<nBits>::iteratorBase
00857 Foam::PackedList<nBits>::operator[](const label i)
00858 {
00859 return iteratorBase(this, i);
00860 }
00861
00862
00863 namespace Foam
00864 {
00865
00866 template<>
00867 inline void Foam::PackedList<1>::operator=(const unsigned int val)
00868 {
00869 if (val)
00870 {
00871 StorageList::operator=(~0u);
00872 }
00873 else
00874 {
00875 StorageList::operator=(0u);
00876 }
00877 }
00878 }
00879
00880
00881 template<unsigned nBits>
00882 inline void Foam::PackedList<nBits>::operator=(const unsigned int val)
00883 {
00884 if (val)
00885 {
00886 unsigned int fill = val;
00887
00888 if (fill & ~max_value())
00889 {
00890
00891 fill = ~0u;
00892 }
00893 else
00894 {
00895 for (unsigned int i = 1; i < packing(); ++i)
00896 {
00897 fill |= (fill << nBits);
00898 }
00899 }
00900
00901 StorageList::operator=(fill);
00902 }
00903 else
00904 {
00905 StorageList::operator=(0u);
00906 }
00907 }
00908
00909
00910