OpenFOAM logo
Open Source CFD Toolkit

PackedListI.H

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-2005 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 the
00013     Free Software Foundation; either version 2 of the License, or (at your
00014     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, write to the Free Software Foundation,
00023     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00024 
00025 
00026 \*---------------------------------------------------------------------------*/
00027 
00028 #ifndef PackedList_I
00029 #define PackedList_I
00030 
00031 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00032 
00033 namespace Foam
00034 {
00035 
00036 // Convert index into index in integer array
00037 template<int nBits>
00038 inline label PackedList<nBits>::intIndex(const label i)
00039 {
00040     const label nElemsPerLabel = sizeof(unsigned int)*8/nBits;
00041 
00042     // Index in underlying int array
00043     label elemI = i/nElemsPerLabel;
00044 
00045     return elemI;
00046 }
00047 
00048 
00049 // Check index i is within valid range (0 ... size-1).
00050 template<int nBits>
00051 inline void PackedList<nBits>::checkIndex(const label i) const
00052 {
00053     if (!size_)
00054     {
00055         FatalErrorIn("PackedList<nBits>::checkIndex(const label)")
00056             << "attempt to access element from zero sized list"
00057             << abort(FatalError);
00058     }
00059     else if (i<0 || i>=size_)
00060     {
00061         FatalErrorIn("PackedList<nBits>::checkIndex(const label)")
00062             << "index " << i << " out of range 0 ... " << size_-1
00063             << abort(FatalError);
00064     }
00065 }
00066 
00067 
00068 // Check value is representable in nBits
00069 template<int nBits>
00070 inline void PackedList<nBits>::checkValue(const unsigned int val) const
00071 {
00072     if (val>=(1u << nBits))
00073     {
00074         FatalErrorIn("PackedList<T>::set(const unsigned int)")
00075             << "value " << label(val) << " out of range 0 ... "
00076             << label((1u << nBits)-1)
00077             << " representable by " << nBits << " bits"
00078             << abort(FatalError);
00079     }
00080 }
00081 
00082 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00083 
00084 // Null constructor
00085 template<int nBits>
00086 inline PackedList<nBits>::PackedList()
00087 :
00088     List<unsigned int>(0),
00089     size_(0)
00090 {}
00091 
00092 
00093 // Construct with given size.
00094 template<int nBits>
00095 inline PackedList<nBits>::PackedList(const label size)
00096 :
00097     List<unsigned int>(intIndex(size-1)+1, 0u),
00098     size_(size)
00099 {}
00100 
00101 
00102 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00103 
00104 template<int nBits>
00105 inline label PackedList<nBits>::size() const
00106 {
00107     return size_;
00108 }
00109 
00110 
00111 // Get value at i
00112 template<int nBits>
00113 inline unsigned int PackedList<nBits>::get(const label i) const
00114 {
00115 #   ifdef DEBUGList
00116     checkIndex(i);
00117 #   endif
00118 
00119     // Constant: number of elements that fit in an unsigned int
00120     const label nElemsPerLabel = sizeof(unsigned int)*8/nBits;
00121 
00122     unsigned int mask = ((1u << nBits) - 1);
00123 
00124     label indexInLabel = i % nElemsPerLabel;
00125 
00126     // Starting bit in int.
00127     label startBit = nBits*indexInLabel;
00128 
00129     return (List<unsigned int>::operator[](intIndex(i)) >> startBit) & mask;
00130 }
00131 
00132 
00133 template<int nBits>
00134 inline unsigned int PackedList<nBits>::operator[](const label i) const
00135 {
00136     return get(i);
00137 }
00138 
00139 
00140 // Set value at i
00141 template<int nBits>
00142 inline void PackedList<nBits>::set(const label i, const unsigned int val)
00143 {
00144 #   ifdef DEBUGList
00145     checkIndex(i);
00146     checkValue(val);
00147 #   endif
00148 
00149     // Constant: number of elements that fit in an unsigned int
00150     const label nElemsPerLabel = sizeof(unsigned int)*8/nBits;
00151 
00152     unsigned int mask = ((1u << nBits) - 1);
00153 
00154     label indexInLabel = i % nElemsPerLabel;
00155 
00156     // Starting bit in int.
00157     label startBit = nBits*indexInLabel;
00158 
00159 
00160     unsigned int shiftedMask = mask << startBit;
00161 
00162     unsigned int shiftedVal = val << startBit;
00163 
00164     unsigned int& elem = List<unsigned int>::operator[](intIndex(i));
00165 
00166     elem = (elem & ~shiftedMask) | shiftedVal;
00167 }
00168 
00169 
00170 template<int nBits>
00171 inline ::Foam::reference PackedList<nBits>::operator[](const label i)
00172 {
00173 #   ifdef DEBUGList
00174     checkIndex(i);
00175 #   endif
00176 
00177     // Constant: number of elements that fit in an unsigned int
00178     const label nElemsPerLabel = sizeof(unsigned int)*8/nBits;
00179 
00180     unsigned int mask = ((1u << nBits) - 1);
00181 
00182     label indexInLabel = i % nElemsPerLabel;
00183 
00184     // Starting bit in int.
00185     label startBit = nBits*indexInLabel;
00186 
00187     unsigned int& elem = List<unsigned int>::operator[](intIndex(i));
00188 
00189     return ::Foam::reference(elem, mask, startBit);
00190 }
00191 
00192 
00193 // Set all to val
00194 template<int nBits>
00195 inline void PackedList<nBits>::operator=(const unsigned int val)
00196 {
00197 #   ifdef DEBUGList
00198     checkValue(val);
00199 #   endif
00200     List<unsigned int>::operator=(val);
00201 }
00202 
00203 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00204 
00205 } // End namespace Foam
00206 
00207 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00208 
00209 #endif
00210 
00211 // ************************************************************************* //
For further information go to www.openfoam.org