Loading...
Searching...
No Matches
PackedList.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2018-2025 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "PackedList.H"
29
30// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
31
32template<unsigned Width>
34(
35 const PackedList<Width>& list,
36 const labelUList& addr
37)
38:
39 PackedList<Width>(addr.size())
40{
41 const label len = addr.size();
42
43 for (label i = 0; i < len; ++i)
44 {
45 set(i, list.get(addr[i]));
46 }
47}
48
49
50template<unsigned Width>
51template<class Addr>
53(
54 const PackedList<Width>& list,
55 const IndirectListBase<label, Addr>& addr
56)
57:
58 PackedList<Width>(addr.size())
59{
60 const label len = addr.size();
61
62 for (label i = 0; i < len; ++i)
63 {
64 set(i, list.get(addr[i]));
65 }
66}
67
68
69template<unsigned Width>
71(
72 const PackedList<Width>& list,
73 const labelRange& range
74)
75:
76 PackedList<Width>(range.size())
77{
78 label pos = range.start();
79 const label len = range.size();
80
81 for (label i = 0; i < len; ++i)
82 {
83 set(i, list.get(pos));
84 ++pos;
85 }
86}
87
88
89// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
90
91template<unsigned Width>
93{
94 // Trivial cases
95 if (empty())
96 {
97 return false;
98 }
99 else if (size() == 1)
100 {
101 return true;
102 }
103
104 // The value of the first element for testing
105 const unsigned int val = get(0);
106
107 bool identical = true;
108
109 if (!val)
110 {
111 // No bits set: just check there are no non-zero blocks
112 // - like bitSet::none()
113 identical = (-1 == first_block());
114 }
115 else if (val == PackedList<Width>::max_value)
116 {
117 // All bits set: just check there are no zero blocks
118 // - like bitSet::all()
119 identical = (-1 == first_not_block());
120 }
121 else
122 {
123 const label nblocks = num_blocks(size());
124
125 if (nblocks > 1)
126 {
127 // Fill value for complete blocks
128 const unsigned int blockval = repeated_value(val);
129
130 // Check each complete block (nblocks-1)
131 for (label blocki = 0; identical && blocki < (nblocks-1); ++blocki)
132 {
133 identical = (blocks_[blocki] == blockval);
134 }
135 }
136
137 // Partial block: check manually
138 for
139 (
140 label elemi = elem_per_block*(nblocks-1);
141 identical && elemi < size();
142 ++elemi
143 )
144 {
145 identical = (val == get(elemi));
146 }
148
149 return identical;
150}
151
152
153template<unsigned Width>
154bool Foam::PackedList<Width>::equal(const PackedList<Width>& other) const
155{
156 if (size() != other.size())
157 {
158 return false;
159 }
160
161 const label nblocks = num_blocks(size());
162 const auto& rhs = other.blocks_;
163
164 for (label blocki = 0; blocki < nblocks; ++blocki)
165 {
166 if (blocks_[blocki] != rhs[blocki])
167 {
168 return false;
169 }
171
172 return true;
173}
174
175
176template<unsigned Width>
178{
179 return this->unpack<label>();
180}
181
182
183template<unsigned Width>
184template<class IntType>
187{
188 static_assert
189 (
190 std::is_integral_v<IntType>,
191 "Integral required for output."
192 );
193 static_assert
194 (
195 Width < std::numeric_limits<IntType>::digits,
196 "Width of IntType is too small to hold result"
197 );
198
199 List<IntType> output(size());
200
201 if (empty())
202 {
203 return output;
204 }
205 else if (uniform())
206 {
207 output = static_cast<IntType>(get(0));
208 return output;
209 }
210
211 // NON-UNIFORM and len > 0
212
213 label outi = 0;
214
215 // Process n-1 complete blocks
216 const label nblocks = num_blocks(size());
217
218 for (label blocki=0; blocki < nblocks-1; ++blocki)
219 {
220 unsigned int blockval = blocks_[blocki];
221
222 for (unsigned nget = elem_per_block; nget; --nget, ++outi)
223 {
224 output[outi] = IntType(blockval & PackedList<Width>::max_value);
225 blockval >>= Width;
226 }
227 }
228
229 // Any partial blocks
230 for (/*nil*/; outi < size(); ++outi)
231 {
232 output[outi] = get(outi);
233 }
234
235 return output;
236}
237
238
239template<unsigned Width>
240template<class IntType>
243{
244 static_assert
245 (
246 std::is_integral_v<IntType>,
247 "Integral required for unpack output."
248 );
249 static_assert
250 (
251 Width < std::numeric_limits<IntType>::digits,
252 "Width of IntType is too small to hold unpack output."
253 );
254
255
256 // Could be more efficient but messier with block-wise access.
257 // - automatically handles any invalid positions
258
259 auto pos = range.start();
260
261 List<IntType> output(range.size());
262
263 for (IntType& out : output)
264 {
265 out = IntType(get(pos));
266 ++pos;
267 }
268
269 return output;
270}
271
272
273template<unsigned Width>
274template<class IntType>
276Foam::PackedList<Width>::unpack(const labelUList& locations) const
277{
278 static_assert
279 (
280 std::is_integral_v<IntType>,
281 "Integral required for unpack output."
282 );
283 static_assert
284 (
285 Width < std::numeric_limits<IntType>::digits,
286 "Width of IntType is too small to hold unpack output."
287 );
288
289
290 label pos = 0;
291
292 List<IntType> output(locations.size());
293
294 for (IntType& out : output)
295 {
296 out = IntType(get(locations[pos]));
297 ++pos;
298 }
299
300 return output;
301}
302
303
304// ************************************************************************* //
scalar range
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
label size() const noexcept
The number of elements in the list.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
label first_block() const
Find the first block with a '1' bit.
bool equal(const PackedList< Width > &other) const
Test for equality of sizes and the bits set.
Definition PackedList.C:147
block_container blocks_
The blocks of raw data.
Definition PackedList.H:224
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
Definition PackedList.H:387
labelList values() const
Return the values as a list of labels.
Definition PackedList.C:170
List< IntType > unpack() const
Return the values as a list of integral type.
static constexpr block_type max_value
The max value for an element which is also the bit-mask of the individual element.
Definition PackedList.H:182
static unsigned int repeated_value(unsigned val)
Enforce non-zero Width to fit within the block storage and require at least 2 items per storage block...
Definition PackedListI.H:27
bool set(const label i, unsigned int val=~0u)
Set value at index i, default value set is the max_value.
bool uniform() const
True if all entries have identical values (and list is non-empty).
Definition PackedList.C:85
unsigned int get(const label i) const
Get value at index i or 0 for out-of-range.
constexpr PackedList() noexcept
Default construct, zero-sized and no allocation.
static constexpr unsigned elem_per_block
The number of elements stored per data block.
Definition PackedList.H:174
static constexpr label num_blocks(label numElem) noexcept
Calculate the number of blocks required to _address_ the requested number of elements.
Definition PackedList.H:196
label size() const noexcept
Number of entries.
Definition PackedList.H:392
label first_not_block() const
Find the first block with a '0' bit.
Foam::List< IntType > unpack() const
Definition PackedList.C:179
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
A range or interval of labels defined by a start and a size.
Definition labelRange.H:66
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
dimensionedScalar pos(const dimensionedScalar &ds)
List< label > labelList
A List of labels.
Definition List.H:62
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
UList< label > labelUList
A UList of labels.
Definition UList.H:75