1 /*---------------------------------------------------------------------------*\
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 -------------------------------------------------------------------------------
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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "PackedList.H"
28 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
30 template<unsigned nBits>
31 Foam::PackedList<nBits>::PackedList(const label size, const unsigned int val)
33 StorageList(packedLength(size), 0u),
40 template<unsigned nBits>
41 Foam::PackedList<nBits>::PackedList(const UList<label>& lst)
43 StorageList(packedLength(lst.size()), 0u),
53 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
56 #if (UINT_MAX == 0xFFFFFFFF)
57 // 32-bit counting, Hamming weight method
58 # define COUNT_PACKEDBITS(sum, x) \
60 x -= (x >> 1) & 0x55555555; \
61 x = (x & 0x33333333) + ((x >> 2) & 0x33333333); \
62 sum += (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; \
64 #elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF)
65 // 64-bit counting, Hamming weight method
66 # define COUNT_PACKEDBITS(sum, x) \
68 x -= (x >> 1) & 0x5555555555555555; \
69 x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333); \
70 sum += (((x + (x >> 4)) & 0x0F0F0F0F0F0F0F0F) * 0x0101010101010101) >> 56;\
73 // Arbitrary number of bits, Brian Kernighan's method
74 # define COUNT_PACKEDBITS(sum, x) for (; x; ++sum) { x &= x - 1; }
78 template<unsigned nBits>
79 unsigned int Foam::PackedList<nBits>::count() const
81 register unsigned int c = 0;
85 // mask value for complete segments
86 unsigned int mask = maskLower(packing());
88 const unsigned int endSeg = size_ / packing();
89 const unsigned int endOff = size_ % packing();
91 // count bits in complete segments
92 for (unsigned i = 0; i < endSeg; ++i)
94 register unsigned int bits = StorageList::operator[](i) & mask;
95 COUNT_PACKEDBITS(c, bits);
98 // count bits in partial segment
101 mask = maskLower(endOff);
103 register unsigned int bits = StorageList::operator[](endSeg) & mask;
104 COUNT_PACKEDBITS(c, bits);
112 template<unsigned nBits>
113 bool Foam::PackedList<nBits>::trim()
120 // mask value for complete segments
121 unsigned int mask = maskLower(packing());
123 label currElem = packedLength(size_) - 1;
124 unsigned int endOff = size_ % packing();
126 // clear trailing bits on final segment
129 StorageList::operator[](currElem) &= maskLower(endOff);
132 // test entire segment
133 while (currElem > 0 && !(StorageList::operator[](currElem) &= mask))
139 label newsize = (currElem + 1) * packing();
141 // mask for the final segment
142 mask = max_value() << (nBits * (packing() - 1));
144 for (endOff = packing(); endOff >= 1; --endOff, --newsize)
146 if (StorageList::operator[](currElem) & mask)
154 if (size_ == newsize)
164 template<unsigned nBits>
165 void Foam::PackedList<nBits>::flip()
167 label packLen = packedLength(size_);
169 for (label i=0; i < packLen; i++)
171 StorageList::operator[](i) = ~StorageList::operator[](i);
176 template<unsigned nBits>
177 Foam::labelList Foam::PackedList<nBits>::values() const
179 labelList elems(size_);
189 template<unsigned nBits>
190 Foam::Ostream& Foam::PackedList<nBits>::iteratorBase::print(Ostream& os) const
192 os << "iterator<" << label(nBits) << "> ["
193 << this->index_ << "]"
194 << " segment:" << label(this->index_ / packing())
195 << " offset:" << label(this->index_ % packing())
196 << " value:" << this->get()
203 template<unsigned nBits>
204 Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
206 const label packLen = packedLength(size_);
208 os << "PackedList<" << nBits << ">"
209 << " max_value:" << max_value()
210 << " packing:" << packing() << nl
211 << " count: " << count() << nl
212 << " size/capacity: " << size_ << "/" << capacity() << nl
213 << " storage/capacity: " << packLen << "/" << StorageList::size()
216 // mask value for complete segments
217 unsigned int mask = maskLower(packing());
219 for (label i=0; i < packLen; i++)
221 const StorageType& rawBits = StorageList::operator[](i);
223 // the final segment may not be full, modify mask accordingly
226 unsigned int endOff = size_ % packing();
230 mask = maskLower(endOff);
238 for (unsigned int testBit = (1u << max_bits()); testBit; testBit >>= 1)
242 if (rawBits & testBit)
264 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
266 template<unsigned nBits>
267 void Foam::PackedList<nBits>::operator=(const PackedList<nBits>& lst)
269 StorageList::operator=(lst);
274 template<unsigned nBits>
275 void Foam::PackedList<nBits>::operator=(const UList<label>& lst)
277 setCapacity(lst.size());
287 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
289 //template<unsigned nBits>
290 //Foam::Ostream& ::Foam::operator<<(Ostream& os, const PackedList<nBits>& lst)
297 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
299 // ************************************************************************* //