00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef PackedList_I
00029 #define PackedList_I
00030
00031
00032
00033 namespace Foam
00034 {
00035
00036
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
00043 label elemI = i/nElemsPerLabel;
00044
00045 return elemI;
00046 }
00047
00048
00049
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
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
00083
00084
00085 template<int nBits>
00086 inline PackedList<nBits>::PackedList()
00087 :
00088 List<unsigned int>(0),
00089 size_(0)
00090 {}
00091
00092
00093
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
00103
00104 template<int nBits>
00105 inline label PackedList<nBits>::size() const
00106 {
00107 return size_;
00108 }
00109
00110
00111
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
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
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
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
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
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
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
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
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 }
00206
00207
00208
00209 #endif
00210
00211