Report patch name instead of index in debug
[foam-extend-3.2.git] / src / foam / containers / Lists / PackedList / PackedListI.H
bloba9a3b5e9e077ed7366258295700dd57616fe2008
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation, either version 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
25 \*---------------------------------------------------------------------------*/
27 #include "error.H"
28 #include <climits>
30 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 template<unsigned nBits>
33 inline unsigned int Foam::PackedList<nBits>::max_bits()
35     return sizeof(StorageType)*CHAR_BIT - 1;
39 template<unsigned nBits>
40 inline unsigned int Foam::PackedList<nBits>::max_value()
42     return (1u << nBits) - 1;
46 template<unsigned nBits>
47 inline unsigned int Foam::PackedList<nBits>::packing()
49     return sizeof(StorageType)*CHAR_BIT / nBits;
53 template<unsigned nBits>
54 inline unsigned int Foam::PackedList<nBits>::maskLower(unsigned offset)
56     // return (1u << (nBits * offset)) - 1;
57     // The next one works more reliably with overflows
58     // eg, when compiled without optimization
59     return (~0u >> ( sizeof(StorageType)*CHAR_BIT - nBits * offset));
63 template<unsigned nBits>
64 inline Foam::label Foam::PackedList<nBits>::packedLength(const label nElem)
66     return (nElem + packing() - 1) / packing();
70 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
72 template<unsigned nBits>
73 inline Foam::PackedList<nBits>::PackedList()
75     StorageList(),
76     size_(0)
80 template<unsigned nBits>
81 inline Foam::PackedList<nBits>::PackedList(const label size)
83     StorageList(packedLength(size), 0u),
84     size_(size)
88 template<unsigned nBits>
89 inline Foam::PackedList<nBits>::PackedList(const PackedList<nBits>& lst)
91     StorageList(lst),
92     size_(lst.size_)
96 template<unsigned nBits>
97 inline Foam::PackedList<nBits>::PackedList(const Xfer<PackedList<nBits> >& lst)
99     transfer(lst());
103 template<unsigned nBits>
104 inline Foam::autoPtr<Foam::PackedList<nBits> >
105 Foam::PackedList<nBits>::clone() const
107     return autoPtr<PackedList<nBits> >(new PackedList<nBits>(*this));
111 // * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
113 // iteratorBase
115 template<unsigned nBits>
116 inline Foam::PackedList<nBits>::iteratorBase::iteratorBase()
118     list_(0),
119     index_(0)
123 template<unsigned nBits>
124 inline Foam::PackedList<nBits>::iteratorBase::iteratorBase
126     const PackedList<nBits>* lst,
127     const label i
130     list_(const_cast<PackedList<nBits>*>(lst)),
131     index_(i)
135 template<unsigned nBits>
136 inline unsigned int
137 Foam::PackedList<nBits>::iteratorBase::get() const
139     const unsigned int seg = index_ / packing();
140     const unsigned int off = index_ % packing();
142     const unsigned int& stored = list_->StorageList::operator[](seg);
143     return (stored >> (nBits * off)) & max_value();
147 template<unsigned nBits>
148 inline bool
149 Foam::PackedList<nBits>::iteratorBase::set(const unsigned int val)
151     const unsigned int seg = index_ / packing();
152     const unsigned int off = index_ % packing();
154     unsigned int& stored = list_->StorageList::operator[](seg);
155     const unsigned int prev = stored;
157     const unsigned int startBit = nBits * off;
158     const unsigned int maskNew  = max_value() << startBit;
160     if (val & ~max_value())
161     {
162         // overflow is max_value, fill everything
163         stored |= maskNew;
164     }
165     else
166     {
167         stored &= ~maskNew;
168         stored |= maskNew & (val << startBit);
169     }
171     return prev != stored;
175 template<unsigned nBits>
176 inline bool Foam::PackedList<nBits>::iteratorBase::operator==
178     const iteratorBase& iter
179 ) const
181     return this->get() == iter.get();
185 template<unsigned nBits>
186 inline bool Foam::PackedList<nBits>::iteratorBase::operator!=
188     const iteratorBase& iter
189 ) const
191     return this->get() != iter.get();
195 template<unsigned nBits>
196 inline unsigned int
197 Foam::PackedList<nBits>::iteratorBase::operator=(const iteratorBase& iter)
199     const unsigned int val = iter.get();
200     this->set(val);
201     return val;
205 template<unsigned nBits>
206 inline unsigned int
207 Foam::PackedList<nBits>::iteratorBase::operator=(const unsigned int val)
209     // lazy evaluation - increase size on assigment
210     if (index_ >= list_->size_)
211     {
212         list_->resize(index_ + 1);
213     }
215     this->set(val);
216     return val;
220 template<unsigned nBits>
221 inline Foam::PackedList<nBits>::iteratorBase::operator
222 unsigned int () const
224     // lazy evaluation - return 0 for out-of-range
225     if (index_ >= list_->size_)
226     {
227         return 0;
228     }
230     return this->get();
234 // const_iterator, iterator
236 template<unsigned nBits>
237 inline Foam::PackedList<nBits>::iterator::iterator()
239     iteratorBase()
243 template<unsigned nBits>
244 inline Foam::PackedList<nBits>::const_iterator::const_iterator()
246     iteratorBase()
250 template<unsigned nBits>
251 inline Foam::PackedList<nBits>::iterator::iterator
253     const iteratorBase& iter
256     iteratorBase(iter)
258     // avoid going past end()
259     // eg, iter = iterator(list, Inf)
260     if (this->index_ > this->list_->size_)
261     {
262         this->index_ = this->list_->size_;
263     }
267 template<unsigned nBits>
268 inline Foam::PackedList<nBits>::const_iterator::const_iterator
270     const iteratorBase& iter
273     iteratorBase(iter)
275     // avoid going past end()
276     // eg, iter = iterator(list, Inf)
277     if (this->index_ > this->list_->size_)
278     {
279         this->index_ = this->list_->size_;
280     }
284 template<unsigned nBits>
285 inline Foam::PackedList<nBits>::iterator::iterator
287     const PackedList<nBits>* lst,
288     const label i
291     iteratorBase(lst, i)
295 template<unsigned nBits>
296 inline Foam::PackedList<nBits>::const_iterator::const_iterator
298     const PackedList<nBits>* lst,
299     const label i
302     iteratorBase(lst, i)
306 template<unsigned nBits>
307 inline Foam::PackedList<nBits>::const_iterator::const_iterator
309     const iterator& iter
312     iteratorBase(static_cast<const iteratorBase&>(iter))
316 template<unsigned nBits>
317 inline bool Foam::PackedList<nBits>::iterator::operator==
319     const iteratorBase& iter
320 ) const
322     return this->index_ == iter.index_;
326 template<unsigned nBits>
327 inline bool Foam::PackedList<nBits>::iterator::operator!=
329     const iteratorBase& iter
330 ) const
332     return this->index_ != iter.index_;
337 template<unsigned nBits>
338 inline bool Foam::PackedList<nBits>::const_iterator::operator==
340     const iteratorBase& iter
341 ) const
343     return this->index_ == iter.index_;
347 template<unsigned nBits>
348 inline bool Foam::PackedList<nBits>::const_iterator::operator!=
350     const iteratorBase& iter
351 ) const
353     return this->index_ != iter.index_;
358 template<unsigned nBits>
359 inline typename Foam::PackedList<nBits>::iterator&
360 Foam::PackedList<nBits>::iterator::operator=(const iteratorBase& iter)
362     this->list_  = iter.list_;
363     this->index_ = iter.index_;
365     // avoid going past end()
366     // eg, iter = iterator(list, Inf)
367     if (this->index_ > this->list_->size_)
368     {
369         this->index_ = this->list_->size_;
370     }
372     return *this;
376 template<unsigned nBits>
377 inline typename Foam::PackedList<nBits>::const_iterator&
378 Foam::PackedList<nBits>::const_iterator::operator=(const iteratorBase& iter)
380     this->list_  = iter.list_;
381     this->index_ = iter.index_;
383     // avoid going past end()
384     // eg, iter = iterator(list, Inf)
385     if (this->index_ > this->list_->size_)
386     {
387         this->index_ = this->list_->size_;
388     }
390     return *this;
394 template<unsigned nBits>
395 inline typename Foam::PackedList<nBits>::iterator&
396 Foam::PackedList<nBits>::iterator::operator++()
398     ++this->index_;
399     return *this;
403 template<unsigned nBits>
404 inline typename Foam::PackedList<nBits>::const_iterator&
405 Foam::PackedList<nBits>::const_iterator::operator++()
407     ++this->index_;
408     return *this;
412 template<unsigned nBits>
413 inline typename Foam::PackedList<nBits>::iterator
414 Foam::PackedList<nBits>::iterator::operator++(int)
416     iterator old = *this;
417     ++this->index_;
418     return old;
422 template<unsigned nBits>
423 inline typename Foam::PackedList<nBits>::const_iterator
424 Foam::PackedList<nBits>::const_iterator::operator++(int)
426     const_iterator old = *this;
427     ++this->index_;
428     return old;
432 template<unsigned nBits>
433 inline typename Foam::PackedList<nBits>::iterator&
434 Foam::PackedList<nBits>::iterator::operator--()
436     --this->index_;
437     return *this;
441 template<unsigned nBits>
442 inline typename Foam::PackedList<nBits>::const_iterator&
443 Foam::PackedList<nBits>::const_iterator::operator--()
445     --this->index_;
446     return *this;
450 template<unsigned nBits>
451 inline typename Foam::PackedList<nBits>::iterator
452 Foam::PackedList<nBits>::iterator::operator--(int)
454     iterator old = *this;
455     --this->index_;
456     return old;
460 template<unsigned nBits>
461 inline typename Foam::PackedList<nBits>::const_iterator
462 Foam::PackedList<nBits>::const_iterator::operator--(int)
464     const_iterator old = *this;
465     --this->index_;
466     return old;
470 template<unsigned nBits>
471 inline typename Foam::PackedList<nBits>::iteratorBase&
472 Foam::PackedList<nBits>::iterator::operator*()
474     return static_cast<iteratorBase&>(*this);
478 template<unsigned nBits>
479 inline typename Foam::PackedList<nBits>::iteratorBase&
480 Foam::PackedList<nBits>::iterator::operator()()
482     return static_cast<iteratorBase&>(*this);
486 template<unsigned nBits>
487 inline unsigned int
488 Foam::PackedList<nBits>::const_iterator::operator*() const
490     return this->get();
494 template<unsigned nBits>
495 inline unsigned int
496 Foam::PackedList<nBits>::const_iterator::operator()() const
498     return this->get();
502 template<unsigned nBits>
503 inline typename Foam::PackedList<nBits>::iterator
504 Foam::PackedList<nBits>::begin()
506     return iterator(this, 0);
510 template<unsigned nBits>
511 inline typename Foam::PackedList<nBits>::const_iterator
512 Foam::PackedList<nBits>::begin() const
514     return const_iterator(this, 0);
518 template<unsigned nBits>
519 inline typename Foam::PackedList<nBits>::const_iterator
520 Foam::PackedList<nBits>::cbegin() const
522     return const_iterator(this, 0);
526 template<unsigned nBits>
527 inline typename Foam::PackedList<nBits>::iterator
528 Foam::PackedList<nBits>::end()
530     return iterator(this, size_);
534 template<unsigned nBits>
535 inline typename Foam::PackedList<nBits>::const_iterator
536 Foam::PackedList<nBits>::end() const
538     return const_iterator(this, size_);
542 template<unsigned nBits>
543 inline typename Foam::PackedList<nBits>::const_iterator
544 Foam::PackedList<nBits>::cend() const
546     return const_iterator(this, size_);
550 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
552 template<unsigned nBits>
553 inline Foam::label Foam::PackedList<nBits>::size() const
555     return size_;
559 template<unsigned nBits>
560 inline bool Foam::PackedList<nBits>::empty() const
562     return !size_;
566 template<unsigned nBits>
567 inline void Foam::PackedList<nBits>::resize
569     const label nElem,
570     const unsigned int& val
573     reserve(nElem);
575     if (nElem > size_)
576     {
577         // fill new elements or newly exposed elements
578         if (size_)
579         {
580             // fill value for complete segments
581             unsigned int fill = val;
583             if (fill & ~max_value())
584             {
585                 // overflow is max_value, fill everything
586                 fill = ~0u;
587             }
588             else
589             {
590                 for (unsigned int i = 1; i < packing(); ++i)
591                 {
592                     fill |= (fill << nBits);
593                 }
594             }
596             unsigned int seg = size_ / packing();
597             unsigned int off = size_ % packing();
599             // partial segment, preserve existing value
600             if (off)
601             {
602                 unsigned int maskOld = maskLower(off);
604                 StorageList::operator[](seg) &= maskOld;
605                 StorageList::operator[](seg) |= ~maskOld & fill;
607                 // continue with the next segment
608                 seg++;
609             }
611             unsigned int endSeg = nElem / packing();
612             // fill in complete elements
613             while (seg < endSeg)
614             {
615                 StorageList::operator[](seg++) = fill;
616             }
617         }
618         else
619         {
620             // no original size - simply flood-fill
621             operator=(val);
622         }
623     }
625     size_ = nElem;
629 template<unsigned nBits>
630 inline void Foam::PackedList<nBits>::setSize
632     const label newSize,
633     const unsigned int& val
636     resize(newSize, val);
641 template<unsigned nBits>
642 inline Foam::label Foam::PackedList<nBits>::capacity() const
644     return packing() * StorageList::size();
648 template<unsigned nBits>
649 inline void Foam::PackedList<nBits>::setCapacity(const label nElem)
651     StorageList::setSize(packedLength(nElem), 0u);
653     // truncate addressed size too?
654     if (size_ > nElem)
655     {
656         size_ = nElem;
657     }
661 template<unsigned nBits>
662 inline void Foam::PackedList<nBits>::reserve
664     const label nElem
667     label len = packedLength(nElem);
669     // need more capacity?
670     if (len > StorageList::size())
671     {
672         // Like DynamicList with SizeInc=0, SizeMult=2, SizeDiv=1
673         StorageList::setSize
674         (
675             max
676             (
677                 len,
678                 StorageList::size()*2
679             ),
680             0u
681         );
682     }
686 template<unsigned nBits>
687 inline void Foam::PackedList<nBits>::clear()
689     size_ = 0;
693 template<unsigned nBits>
694 inline void Foam::PackedList<nBits>::clearStorage()
696     StorageList::clear();
697     size_ = 0;
701 template<unsigned nBits>
702 inline void Foam::PackedList<nBits>::shrink()
704     label len = packedLength(size_);
706     // we have unused space?
707     if (len < StorageList::size())
708     {
709         StorageList::setSize(len);
710     }
713 template<unsigned nBits>
714 inline Foam::List<unsigned int>&
715 Foam::PackedList<nBits>::storage()
717     return static_cast<StorageList&>(*this);
721 template<unsigned nBits>
722 inline const Foam::List<unsigned int>&
723 Foam::PackedList<nBits>::storage() const
725     return static_cast<const StorageList&>(*this);
729 template<unsigned nBits>
730 inline void Foam::PackedList<nBits>::transfer(PackedList<nBits>& lst)
732     size_ = lst.size_;
733     lst.size_ = 0;
735     StorageList::transfer(lst);
739 template<unsigned nBits>
740 inline Foam::Xfer< Foam::PackedList<nBits> >
741 Foam::PackedList<nBits>::xfer()
743     return xferMove(*this);
747 template<unsigned nBits>
748 inline unsigned int Foam::PackedList<nBits>::get(const label i) const
750 #   ifdef FULLDEBUG
751     if (i < 0)
752     {
753         FatalErrorIn("PackedList<nBits>::get(const label)")
754             << "negative index " << i << " max=" << size_-1
755             << abort(FatalError);
756     }
757 #   endif
759     // lazy evaluation - return 0 for out-of-range
760     if (i < size_)
761     {
762         return iteratorBase(this, i).get();
763     }
764     else
765     {
766         return 0;
767     }
771 template<unsigned nBits>
772 inline unsigned int Foam::PackedList<nBits>::operator[](const label i) const
774     // lazy evaluation - return 0 for out-of-range
775     if (i < size_)
776     {
777         return iteratorBase(this, i).get();
778     }
779     else
780     {
781         return 0;
782     }
786 template<unsigned nBits>
787 inline bool Foam::PackedList<nBits>::set
789     const label i,
790     const unsigned int val
793 #   ifdef FULLDEBUG
794     if (i < 0)
795     {
796         FatalErrorIn("PackedList<nBits>::set(const label)")
797             << "negative index " << i << " max=" << size_-1
798             << abort(FatalError);
799     }
800 #   endif
802     // lazy evaluation - increase size on assigment
803     if (i >= size_)
804     {
805         resize(i + 1);
806     }
808     return iteratorBase(this, i).set(val);
812 template<unsigned nBits>
813 inline bool Foam::PackedList<nBits>::unset(const label i)
815     // lazy - ignore out-of-bounds
816     if (i < 0 || i >= size_)
817     {
818         return false;
819     }
821     return iteratorBase(this, i).set(0u);
825 template<unsigned nBits>
826 inline void Foam::PackedList<nBits>::append(const unsigned int val)
828     label elemI = size_;
829     reserve(elemI + 1);
830     size_++;
832     iteratorBase(this, elemI).set(val);
836 template<unsigned nBits>
837 inline unsigned int Foam::PackedList<nBits>::remove()
839     if (!size_)
840     {
841         FatalErrorIn
842         (
843             "Foam::PackedList<nBits>::remove()"
844         )   << "List is empty" << abort(FatalError);
845     }
847     label elemI = size_ - 1;
848     const unsigned int val = iteratorBase(this, elemI).get();
849     resize(elemI);
851     return val;
855 template<unsigned nBits>
856 inline typename Foam::PackedList<nBits>::iteratorBase
857 Foam::PackedList<nBits>::operator[](const label i)
859     return iteratorBase(this, i);
863 namespace Foam
865     // specialization for nBits=1
866     template<>
867     inline void Foam::PackedList<1>::operator=(const unsigned int val)
868     {
869         if (val)
870         {
871             StorageList::operator=(~0u);
872         }
873         else
874         {
875             StorageList::operator=(0u);
876         }
877     }
881 template<unsigned nBits>
882 inline void Foam::PackedList<nBits>::operator=(const unsigned int val)
884     if (val)
885     {
886         unsigned int fill = val;
888         if (fill & ~max_value())
889         {
890             // treat overflow as max_value
891             fill = ~0u;
892         }
893         else
894         {
895             for (unsigned int i = 1; i < packing(); ++i)
896             {
897                 fill |= (fill << nBits);
898             }
899         }
901         StorageList::operator=(fill);
902     }
903     else
904     {
905         StorageList::operator=(0u);
906     }
910 // ************************************************************************* //