Loading...
Searching...
No Matches
bitSetIO.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 "bitSet.H"
29#include "Switch.H"
30#include "IOstreams.H"
31
32// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
33
34// Format is either of these:
35//
36// <int1> <int2> ( ... )
37// <int1> <int2> { <bool> }
38// where int1 = size, int2 = number of 'on' entries
39// - within the brackets : the locations of the 'on' entries.
40// - within the braces : a uniform set where true = all, false = none
41//
43(
44 Ostream& os,
45 label shortLen
46) const
47{
48 const bitSet& bitset = *this;
49 if (shortLen < 0) shortLen = 1; // <- sanity
50
51 // Size and number of 'ON' entries:
52 const label len = bitset.size();
53 const label tocLen = (bitset.any() ? bitset.count() : 0);
54
55 Switch uniformity =
56 (
57 (tocLen == 0) ? Switch::FALSE // None on
58 : (tocLen == len) ? Switch::TRUE // All on
59 : Switch::INVALID // Mixed
60 );
61
62
63 // Not yet:
64 // if (os.format() == IOstreamOption::BINARY) {}
65
66 if (len > 1 && uniformity.good())
67 {
68 // Two or more entries, and all entries have identical values
69
70 // Count/size and delimiter
71 os << len << token::SPACE << tocLen << token::BEGIN_BLOCK;
72
73 if (uniformity)
74 {
75 os << word("true");
76 }
77 else
78 {
79 os << word("false");
80 }
82
83 }
84 else if (len <= 1 || !shortLen || (len <= shortLen))
85 {
86 // Single-line output
87
88 // Count/size and delimiter
89 os << len << token::SPACE << tocLen << token::BEGIN_LIST;
90
91 label iter = bitset.find_first();
92
93 if (iter >= 0)
94 {
95 os << iter;
96 iter = bitset.find_next(iter);
97 }
98
99 // Contents
100 for (/*nil*/; iter >= 0; iter = bitset.find_next(iter))
101 {
102 os << token::SPACE << iter;
103 }
104
105 // End delimiter
107 }
108 else
109 {
110 // Multi-line output, but with linebreaks according to shortLen
111
112 // Count/size and delimiter
113 os << len << token::SPACE << tocLen << token::BEGIN_LIST;
114
115 label column = 0; // The current output position
116
117 // Contents
118 for
119 (
120 label iter = bitset.find_first();
121 iter >= 0;
122 iter = bitset.find_next(iter)
123 )
124 {
125 if (column >= shortLen) { os << nl; }
126 else if (column) { os << token::SPACE; }
127 ++column;
128 os << iter;
129 }
130
131 // End delimiter
133 }
134
135 return os;
136}
137
138
140{
141 bitSet& bitset = *this;
142
143 // Input errors that may be encountered:
144 enum errorType
145 {
146 ErrorNone = 0, // OK
147 ErrorToken1, // Bad first token
148 ErrorToken2, // Bad second token
149 ErrorSizing, // Bad size (len < tocLen)
150 ErrorBounds, // Bad toc entry
151 };
152 int errorCode(errorType::ErrorNone);
153
154 label len(0);
155 label tocLen(0);
156 label tocEntry(-1); // The toc entry while reading
157
158
159 is.fatalCheck(FUNCTION_NAME);
160
161 token tok(is);
162 is.fatalCheck("bitSet::readTocList() : reading first token");
163
164 if (tok.isLabel())
165 {
166 len = tok.labelToken();
167 tok.read(is);
168
169 if (tok.isLabel())
170 {
171 tocLen = tok.labelToken();
172 if (len < tocLen) { errorCode = errorType::ErrorSizing; }
173 }
174 else
175 {
176 errorCode = errorType::ErrorToken2;
177 }
178 }
179 else
180 {
181 errorCode = errorType::ErrorToken1;
182 }
183
184 if (errorCode == errorType::ErrorNone) do
185 {
186 bitset.clear(); // Clear old contents
187 bitset.resize(len);
188
189 // Not yet:
190 // if (is.format() == IOstreamOption::BINARY) {} else
191 {
192 // Begin of contents marker
193 const char delimiter = is.readBeginList("bitSet");
194
195 if (delimiter == token::BEGIN_LIST)
196 {
197 // Read entries
198 for (label i = 0; i < tocLen; ++i)
199 {
200 is >> tocEntry;
201 is.fatalCheck
202 (
203 "bitSet::readCompact(Istream&) : "
204 "reading entry"
205 );
206
207 if (tocEntry < 0 || tocEntry >= len)
208 {
209 errorCode = errorType::ErrorBounds;
210 break;
211 }
212 else
213 {
214 bitset.set(tocEntry);
215 }
216 }
217 }
218 else
219 {
220 // Uniform content (delimiter == token::BEGIN_BLOCK)
221 Switch uniformity(is);
222
223 is.fatalCheck
224 (
225 "bitSet::readTocList() : "
226 "reading the single entry"
227 );
228
229 // Fill with the value
230 bitset.fill(uniformity);
231 }
232
233 // End of contents marker
234
235 if (errorCode == errorType::ErrorNone)
236 {
237 is.readEndList("bitSet");
238 }
239 }
240 }
241 while (false);
242
243 if (errorCode != errorType::ErrorNone)
244 {
245 auto& err = FatalIOErrorInFunction(is);
246
247 if (errorType::ErrorToken1 == errorCode)
248 {
249 err << "Incorrect first token [size], expected <int>, found "
250 << tok.info() << nl;
251 }
252 else if (errorType::ErrorToken2 == errorCode)
253 {
254 err << "Incorrect second token [toc size], expected <int>, found "
255 << tok.info() << nl;
256 }
257 else if (errorType::ErrorSizing == errorCode)
258 {
259 err << "Bad sizing: has " << tocLen
260 << " entries for a bitSet with size " << len << nl;
261 }
262 else if (errorType::ErrorBounds == errorCode)
263 {
264 err << "Entry " << tocEntry
265 << " not within the expected bounds [0," << len << "]" << nl;
266 }
267 else
268 {
269 err << "Unspecified error" << nl;
270 }
271
272 err << exit(FatalIOError);
273 }
275 return is;
276}
277
278
279// * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * * //
282{
283 return bitset.writeList(os, 40);
284}
285
286
287Foam::Ostream& Foam::operator<<
288(
289 Ostream& os,
290 const InfoProxy<bitSet>& iproxy
291)
292{
293 const auto& bitset = *iproxy;
294
295 os << "bitSet<" << bitSet::elem_per_block
296 << "> size=" << bitset.size() << '/' << bitset.capacity()
297 << " count=" << bitset.count()
298 << nl;
299
300 return os;
301}
302
303
304// ************************************************************************* //
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
bool fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition IOstream.C:51
A helper class for outputting values to Ostream.
Definition InfoProxy.H:49
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition Istream.H:60
char readEndList(const char *funcName)
End read of list data, ends with ')' or '}'.
Definition Istream.C:192
char readBeginList(const char *funcName)
Begin read of list data, starts with '(' or '{'.
Definition Istream.C:171
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
void resize(const label numElem, const unsigned int val=0u)
Reset addressable list size, does not shrink the allocated size.
label capacity() const noexcept
Number of elements that can be stored without reallocating.
Ostream & writeList(Ostream &os, label shortLen=0) const
Write List, with line-breaks in ASCII when length exceeds shortLen.
static constexpr unsigned elem_per_block
Definition PackedList.H:174
label size() const noexcept
Number of entries.
Definition PackedList.H:392
void clear()
Clear the list, i.e. set addressable size to zero.
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition Switch.H:81
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition bitSet.H:61
unsigned int count(const bool on=true) const
Count number of bits set.
Definition bitSetI.H:420
void fill(const bool val)
Assign all entries to the given value.
Definition bitSetI.H:474
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition bitSetI.H:502
constexpr bitSet() noexcept
Default construct an empty, zero-sized bitSet.
Definition bitSetI.H:23
Istream & readListToc(Istream &is)
Read contents in "compact" format, which is the listing of the 'on' bits (toc).
Definition bitSetIO.C:132
Ostream & writeListToc(Ostream &os, label shortLen=0) const
Write contents in "compact" format, which is the listing of the 'on' bits (toc), with line-breaks in ...
Definition bitSetIO.C:36
label find_next(label pos) const
Locate the next bit set, starting one beyond the specified position.
Definition bitSetI.H:347
bool any() const
True if any bits in this bitset are set.
Definition bitSetI.H:408
label find_first() const
Locate the first bit that is set.
Definition bitSetI.H:260
A token holds an item read from Istream.
Definition token.H:70
@ BEGIN_BLOCK
Begin block [isseparator].
Definition token.H:178
@ END_BLOCK
End block [isseparator].
Definition token.H:179
@ BEGIN_LIST
Begin list [isseparator].
Definition token.H:174
@ END_LIST
End list [isseparator].
Definition token.H:175
@ SPACE
Space [isspace].
Definition token.H:144
bool isLabel() const noexcept
Integral token is convertible to Foam::label.
Definition tokenI.H:843
label labelToken() const
Return integer type as label value or Error.
Definition tokenI.H:869
bool read(Istream &is)
Read a token from Istream, calls reset() first.
Definition tokenIO.C:146
InfoProxy< token > info() const noexcept
Return info proxy, for printing token information to a stream.
Definition token.H:1253
A class for handling words, derived from Foam::string.
Definition word.H:66
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
bitSet bitset(const labelHashSet &locations)
Transform the on locations to a bitSet.
Definition HashOps.C:63
uniformity
Classification of list/container uniformity. The values can be used with bit-wise or reduction.
Definition ListPolicy.H:354
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces).
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50