FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

PackedList.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "PackedList.H"
00027 
00028 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00029 
00030 template<unsigned nBits>
00031 Foam::PackedList<nBits>::PackedList(const label size, const unsigned int val)
00032 :
00033     StorageList(packedLength(size), 0u),
00034     size_(size)
00035 {
00036     operator=(val);
00037 }
00038 
00039 
00040 template<unsigned nBits>
00041 Foam::PackedList<nBits>::PackedList(const UList<label>& lst)
00042 :
00043     StorageList(packedLength(lst.size()), 0u),
00044     size_(lst.size())
00045 {
00046     forAll(lst, i)
00047     {
00048         set(i, lst[i]);
00049     }
00050 }
00051 
00052 
00053 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00054 
00055 
00056 #if (UINT_MAX == 0xFFFFFFFF)
00057 // 32-bit counting, Hamming weight method
00058 #   define COUNT_PACKEDBITS(sum, x)                                           \
00059 {                                                                             \
00060     x -= (x >> 1) & 0x55555555;                                               \
00061     x = (x & 0x33333333) + ((x >> 2) & 0x33333333);                           \
00062     sum += (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;                \
00063 }
00064 #elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF)
00065 // 64-bit counting, Hamming weight method
00066 #   define COUNT_PACKEDBITS(sum, x)                                           \
00067 {                                                                             \
00068     x -= (x >> 1) & 0x5555555555555555;                                       \
00069     x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);           \
00070     sum += (((x + (x >> 4)) & 0x0F0F0F0F0F0F0F0F) * 0x0101010101010101) >> 56;\
00071 }
00072 #else
00073 // Arbitrary number of bits, Brian Kernighan's method
00074 #   define COUNT_PACKEDBITS(sum, x)    for (; x; ++sum) { x &= x - 1; }
00075 #endif
00076 
00077 
00078 template<unsigned nBits>
00079 unsigned int Foam::PackedList<nBits>::count() const
00080 {
00081     register unsigned int c = 0;
00082 
00083     if (size_)
00084     {
00085         // mask value for complete segments
00086         unsigned int mask = maskLower(packing());
00087 
00088         const unsigned int endSeg = size_ / packing();
00089         const unsigned int endOff = size_ % packing();
00090 
00091         // count bits in complete segments
00092         for (unsigned i = 0; i < endSeg; ++i)
00093         {
00094             register unsigned int bits = StorageList::operator[](i) & mask;
00095             COUNT_PACKEDBITS(c, bits);
00096         }
00097 
00098         // count bits in partial segment
00099         if (endOff)
00100         {
00101             mask = maskLower(endOff);
00102 
00103             register unsigned int bits = StorageList::operator[](endSeg) & mask;
00104             COUNT_PACKEDBITS(c, bits);
00105         }
00106     }
00107 
00108     return c;
00109 }
00110 
00111 
00112 template<unsigned nBits>
00113 bool Foam::PackedList<nBits>::trim()
00114 {
00115     if (!size_)
00116     {
00117         return false;
00118     }
00119 
00120     // mask value for complete segments
00121     unsigned int mask = maskLower(packing());
00122 
00123     label currElem = packedLength(size_) - 1;
00124     unsigned int endOff = size_ % packing();
00125 
00126     // clear trailing bits on final segment
00127     if (endOff)
00128     {
00129         StorageList::operator[](currElem) &= maskLower(endOff);
00130     }
00131 
00132     // test entire segment
00133     while (currElem > 0 && !(StorageList::operator[](currElem) &= mask))
00134     {
00135         currElem--;
00136     }
00137 
00138     // test segment
00139     label newsize = (currElem + 1) * packing();
00140 
00141     // mask for the final segment
00142     mask = max_value() << (nBits * (packing() - 1));
00143 
00144     for (endOff = packing(); endOff >= 1; --endOff, --newsize)
00145     {
00146         if (StorageList::operator[](currElem) & mask)
00147         {
00148             break;
00149         }
00150 
00151         mask >>= nBits;
00152     }
00153 
00154     if (size_ == newsize)
00155     {
00156         return false;
00157     }
00158 
00159     size_ = newsize;
00160     return false;
00161 }
00162 
00163 
00164 template<unsigned nBits>
00165 void Foam::PackedList<nBits>::flip()
00166 {
00167     label packLen = packedLength(size_);
00168 
00169     for (label i=0; i < packLen; i++)
00170     {
00171         StorageList::operator[](i) = ~StorageList::operator[](i);
00172     }
00173 }
00174 
00175 
00176 template<unsigned nBits>
00177 Foam::labelList Foam::PackedList<nBits>::values() const
00178 {
00179     labelList elems(size_);
00180 
00181     forAll(*this, i)
00182     {
00183         elems[i] = get(i);
00184     }
00185     return elems;
00186 }
00187 
00188 
00189 template<unsigned nBits>
00190 Foam::Ostream& Foam::PackedList<nBits>::iteratorBase::print(Ostream& os) const
00191 {
00192     os  << "iterator<"  << label(nBits) << "> ["
00193         << this->index_ << "]"
00194         << " segment:"  << label(this->index_ / packing())
00195         << " offset:"   << label(this->index_ % packing())
00196         << " value:"    << this->get()
00197         << nl;
00198 
00199     return os;
00200 }
00201 
00202 
00203 template<unsigned nBits>
00204 Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
00205 {
00206     const label packLen = packedLength(size_);
00207 
00208     os  << "PackedList<" << nBits << ">"
00209         << " max_value:" << max_value()
00210         << " packing:"   << packing() << nl
00211         << " count: "     << count() << nl
00212         << " size/capacity: " << size_ << "/" << capacity() << nl
00213         << " storage/capacity: " << packLen << "/" << StorageList::size()
00214         << "\n(\n";
00215 
00216     // mask value for complete segments
00217     unsigned int mask = maskLower(packing());
00218 
00219     for (label i=0; i < packLen; i++)
00220     {
00221         const StorageType& rawBits = StorageList::operator[](i);
00222 
00223         // the final segment may not be full, modify mask accordingly
00224         if (i+1 == packLen)
00225         {
00226             unsigned int endOff = size_ % packing();
00227 
00228             if (endOff)
00229             {
00230                 mask = maskLower(endOff);
00231             }
00232             else
00233             {
00234                 continue;
00235             }
00236         }
00237 
00238         for (unsigned int testBit = (1u << max_bits()); testBit; testBit >>= 1)
00239         {
00240             if (mask & testBit)
00241             {
00242                 if (rawBits & testBit)
00243                 {
00244                     os << '1';
00245                 }
00246                 else
00247                 {
00248                     os << '-';
00249                 }
00250             }
00251             else
00252             {
00253                 os << 'x';
00254             }
00255         }
00256         os << '\n';
00257     }
00258     os << ")\n";
00259 
00260     return os;
00261 }
00262 
00263 
00264 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00265 
00266 template<unsigned nBits>
00267 void Foam::PackedList<nBits>::operator=(const PackedList<nBits>& lst)
00268 {
00269     StorageList::operator=(lst);
00270     size_ = lst.size();
00271 }
00272 
00273 
00274 template<unsigned nBits>
00275 void Foam::PackedList<nBits>::operator=(const UList<label>& lst)
00276 {
00277     setCapacity(lst.size());
00278     size_ = lst.size();
00279 
00280     forAll(lst, i)
00281     {
00282         set(i, lst[i]);
00283     }
00284 }
00285 
00286 
00287 // * * * * * * * * * * * * * * * Ostream Operator *  * * * * * * * * * * * * //
00288 
00289 //template<unsigned nBits>
00290 //Foam::Ostream& ::Foam::operator<<(Ostream& os, const PackedList<nBits>& lst)
00291 //{
00292 //    os << lst();
00293 //    return os;
00294 //}
00295 
00296 
00297 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00298 
00299 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines