initial commit for version 1.5.x patch release
[OpenFOAM-1.5.x.git] / src / OpenFOAM / containers / Lists / PackedList / PackedListI.H
blob42b7afb81a4a32dbfed9d9936bfc0ca2c3344678
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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
26 \*---------------------------------------------------------------------------*/
28 #ifndef PackedList_I
29 #define PackedList_I
31 #include "IOstreams.H"
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 namespace Foam
38 // Calculate underlying list size
39 template<int nBits>
40 inline label PackedList<nBits>::intSize(const label sz)
42     const label nElemsPerLabel = sizeof(unsigned int)*8/nBits;
44     return (sz+nElemsPerLabel-1)/nElemsPerLabel;
48 // Convert index into index in integer array
49 template<int nBits>
50 inline label PackedList<nBits>::intIndex(const label i)
52     const label nElemsPerLabel = sizeof(unsigned int)*8/nBits;
54     // Index in underlying int array
55     label elemI = i/nElemsPerLabel;
57     return elemI;
61 // Check index i is within valid range (0 ... size-1).
62 template<int nBits>
63 inline void PackedList<nBits>::checkIndex(const label i) const
65     if (!size_)
66     {
67         FatalErrorIn("PackedList<nBits>::checkIndex(const label)")
68             << "attempt to access element from zero sized list"
69             << abort(FatalError);
70     }
71     else if (i<0 || i>=size_)
72     {
73         FatalErrorIn("PackedList<nBits>::checkIndex(const label)")
74             << "index " << i << " out of range 0 ... " << size_-1
75             << abort(FatalError);
76     }
80 // Check value is representable in nBits
81 template<int nBits>
82 inline void PackedList<nBits>::checkValue(const unsigned int val) const
84     if (val>=(1u << nBits))
85     {
86         FatalErrorIn("PackedList<T>::set(const unsigned int)")
87             << "value " << label(val) << " out of range 0 ... "
88             << label((1u << nBits)-1)
89             << " representable by " << nBits << " bits"
90             << abort(FatalError);
91     }
94 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
96 // Null constructor
97 template<int nBits>
98 inline PackedList<nBits>::PackedList()
100     List<unsigned int>(0),
101     size_(0)
105 // Construct with given size.
106 template<int nBits>
107 inline PackedList<nBits>::PackedList(const label size)
109     List<unsigned int>(intSize(size), 0u),
110     size_(size)
114 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
116 template<int nBits>
117 inline label PackedList<nBits>::size() const
119     return size_;
123 // Get value at i
124 template<int nBits>
125 inline unsigned int PackedList<nBits>::get(const label i) const
127 #   ifdef DEBUGList
128     checkIndex(i);
129 #   endif
131     // Constant: number of elements that fit in an unsigned int
132     const label nElemsPerLabel = sizeof(unsigned int)*8/nBits;
134     unsigned int mask = ((1u << nBits) - 1);
136     label indexInLabel = i % nElemsPerLabel;
138     // Starting bit in int.
139     label startBit = nBits*indexInLabel;
141     return (List<unsigned int>::operator[](intIndex(i)) >> startBit) & mask;
145 template<int nBits>
146 inline unsigned int PackedList<nBits>::operator[](const label i) const
148     return get(i);
152 // Set value at i
153 template<int nBits>
154 inline bool PackedList<nBits>::set(const label i, const unsigned int val)
156 #   ifdef DEBUGList
157     checkIndex(i);
158     checkValue(val);
159 #   endif
161     // Constant: number of elements that fit in an unsigned int
162     const label nElemsPerLabel = sizeof(unsigned int)*8/nBits;
164     unsigned int mask = ((1u << nBits) - 1);
166     label indexInLabel = i % nElemsPerLabel;
168     // Starting bit in int.
169     label startBit = nBits*indexInLabel;
172     unsigned int shiftedMask = mask << startBit;
174     unsigned int shiftedVal = val << startBit;
176     unsigned int& elem = List<unsigned int>::operator[](intIndex(i));
178     unsigned int oldElem = elem;
180     elem = (elem & ~shiftedMask) | shiftedVal;
182     return elem != oldElem;
186 template<int nBits>
187 inline ::Foam::reference PackedList<nBits>::operator[](const label i)
189 #   ifdef DEBUGList
190     checkIndex(i);
191 #   endif
193     // Constant: number of elements that fit in an unsigned int
194     const label nElemsPerLabel = sizeof(unsigned int)*8/nBits;
196     unsigned int mask = ((1u << nBits) - 1);
198     label indexInLabel = i % nElemsPerLabel;
200     // Starting bit in int.
201     label startBit = nBits*indexInLabel;
203     unsigned int& elem = List<unsigned int>::operator[](intIndex(i));
205     return ::Foam::reference(elem, mask, startBit);
209 // Set all to val
210 template<int nBits>
211 inline void PackedList<nBits>::operator=(const unsigned int val)
213 #   ifdef DEBUGList
214     checkValue(val);
215 #   endif
216     List<unsigned int>::operator=(val);
219 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
221 } // End namespace Foam
223 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
225 #endif
227 // ************************************************************************* //