1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM 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 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "PackedList.H"
29 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
31 template<unsigned nBits>
32 Foam::PackedList<nBits>::PackedList(const label size, const unsigned int val)
34 StorageList(packedLength(size), 0u),
41 template<unsigned nBits>
42 Foam::PackedList<nBits>::PackedList(const UList<label>& lst)
44 StorageList(packedLength(lst.size()), 0u),
54 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
57 #if (UINT_MAX == 0xFFFFFFFF)
58 // 32-bit counting, Hamming weight method
59 # define COUNT_PACKEDBITS(sum, x) \
61 x -= (x >> 1) & 0x55555555; \
62 x = (x & 0x33333333) + ((x >> 2) & 0x33333333); \
63 sum += (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; \
65 #elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF)
66 // 64-bit counting, Hamming weight method
67 # define COUNT_PACKEDBITS(sum, x) \
69 x -= (x >> 1) & 0x5555555555555555; \
70 x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333); \
71 sum += (((x + (x >> 4)) & 0x0F0F0F0F0F0F0F0F) * 0x0101010101010101) >> 56;\
74 // Arbitrary number of bits, Brian Kernighan's method
75 # define COUNT_PACKEDBITS(sum, x) for (; x; ++sum) { x &= x - 1; }
79 template<unsigned nBits>
80 unsigned int Foam::PackedList<nBits>::count() const
82 register unsigned int c = 0;
86 // mask value for complete segments
87 unsigned int mask = maskLower(packing());
89 const unsigned int endSeg = size_ / packing();
90 const unsigned int endOff = size_ % packing();
92 // count bits in complete segments
93 for (unsigned i = 0; i < endSeg; ++i)
95 register unsigned int bits = StorageList::operator[](i) & mask;
96 COUNT_PACKEDBITS(c, bits);
99 // count bits in partial segment
102 mask = maskLower(endOff);
104 register unsigned int bits = StorageList::operator[](endSeg) & mask;
105 COUNT_PACKEDBITS(c, bits);
113 template<unsigned nBits>
114 bool Foam::PackedList<nBits>::trim()
121 // mask value for complete segments
122 unsigned int mask = maskLower(packing());
124 label currElem = packedLength(size_) - 1;
125 unsigned int endOff = size_ % packing();
127 // clear trailing bits on final segment
130 StorageList::operator[](currElem) &= maskLower(endOff);
133 // test entire segment
134 while (currElem > 0 && !(StorageList::operator[](currElem) &= mask))
140 label newsize = (currElem + 1) * packing();
142 // mask for the final segment
143 mask = max_value() << (nBits * (packing() - 1));
145 for (endOff = packing(); endOff >= 1; --endOff, --newsize)
147 if (StorageList::operator[](currElem) & mask)
155 if (size_ == newsize)
165 template<unsigned nBits>
166 void Foam::PackedList<nBits>::flip()
168 label packLen = packedLength(size_);
170 for (label i=0; i < packLen; i++)
172 StorageList::operator[](i) = ~StorageList::operator[](i);
177 template<unsigned nBits>
178 Foam::labelList Foam::PackedList<nBits>::values() const
180 labelList elems(size_);
190 template<unsigned nBits>
191 Foam::Ostream& Foam::PackedList<nBits>::iteratorBase::print(Ostream& os) const
193 os << "iterator<" << label(nBits) << "> ["
194 << this->index_ << "]"
195 << " segment:" << label(this->index_ / packing())
196 << " offset:" << label(this->index_ % packing())
197 << " value:" << this->get()
204 template<unsigned nBits>
205 Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
207 const label packLen = packedLength(size_);
209 os << "PackedList<" << nBits << ">"
210 << " max_value:" << max_value()
211 << " packing:" << packing() << nl
212 << " count: " << count() << nl
213 << " size/capacity: " << size_ << "/" << capacity() << nl
214 << " storage/capacity: " << packLen << "/" << StorageList::size()
217 // mask value for complete segments
218 unsigned int mask = maskLower(packing());
220 for (label i=0; i < packLen; i++)
222 const StorageType& rawBits = StorageList::operator[](i);
224 // the final segment may not be full, modify mask accordingly
227 unsigned int endOff = size_ % packing();
231 mask = maskLower(endOff);
239 for (unsigned int testBit = (1u << max_bits()); testBit; testBit >>= 1)
243 if (rawBits & testBit)
265 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
267 template<unsigned nBits>
268 void Foam::PackedList<nBits>::operator=(const PackedList<nBits>& lst)
270 StorageList::operator=(lst);
275 template<unsigned nBits>
276 void Foam::PackedList<nBits>::operator=(const UList<label>& lst)
278 setCapacity(lst.size());
288 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
290 //template<unsigned nBits>
291 //Foam::Ostream& ::Foam::operator<<(Ostream& os, const PackedList<nBits>& lst)
298 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
300 // ************************************************************************* //