Switch.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2017-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "Switch.H"
30 #include "scalar.H"
31 #include "error.H"
32 #include "dictionary.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace
37 {
38 static_assert
39 (
40  Foam::Switch::INVALID+1 == 9,
41  "Switch::switchType does not have 9 entries"
42 );
43 
44 //- The names corresponding to the Switch::switchType enumeration.
45 // Includes extra entries for "invalid".
46 static const char* names[9] =
47 {
48  "false", "true",
49  "no", "yes",
50  "off", "on",
51  "none", "any",
52  "invalid" //< Output representation only
53 };
54 
55 } // End anonymous namespace
56 
57 
58 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
59 
60 namespace Foam
61 {
62 template<class OS>
63 static OS& printTokenError(OS& os, const token& tok)
64 {
65  if (!tok.good())
66  {
67  os << "Bad token - could not get bool/switch" << nl;
68  }
69  else if (tok.isWord())
70  {
71  os << "Expected true/false, on/off... found "
72  << tok.wordToken() << nl;
73  }
74  else
75  {
76  os << "Wrong token - expected bool/switch, found "
77  << tok.info() << nl;
78  }
79 
80  return os;
81 }
82 } // End namespace Foam
83 
84 
85 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
86 
87 Foam::Switch::switchType Foam::Switch::parse
88 (
89  const std::string& str,
90  const bool failOnError
91 )
92 {
93  switch (str.size())
94  {
95  case 1: // (0|1|f|t|n|y)
96  {
97  switch (str[0])
98  {
99  case '0': case 'f': return switchType::FALSE;
100  case '1': case 't': return switchType::TRUE;
101  case 'n': return switchType::NO;
102  case 'y': return switchType::YES;
103  }
104  break;
105  }
106  case 2: // (no|on)
107  {
108  if (str == names[switchType::NO]) return switchType::NO;
109  if (str == names[switchType::ON]) return switchType::ON;
110  break;
111  }
112  case 3: // (off|yes|any)
113  {
114  if (str == names[switchType::OFF]) return switchType::OFF;
115  if (str == names[switchType::YES]) return switchType::YES;
116  if (str == names[switchType::ANY]) return switchType::ANY;
117  break;
118  }
119  case 4: // (none|true)
120  {
121  if (str == names[switchType::NONE]) return switchType::NONE;
122  if (str == names[switchType::TRUE]) return switchType::TRUE;
123  break;
124  }
125  case 5: // (false)
126  {
127  if (str == names[switchType::FALSE]) return switchType::FALSE;
128  break;
129  }
130  }
131 
132  if (failOnError)
133  {
135  << "Unknown switch " << str << nl
136  << abort(FatalError);
137  }
138 
139  return switchType::INVALID;
140 }
142 
143 // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
144 
145 const char* Foam::Switch::name(const bool b) noexcept
146 {
147  return names[(b ? 1 : 0)];
148 }
149 
150 
151 Foam::Switch Foam::Switch::find(const std::string& str)
152 {
153  return Switch(parse(str, false)); // failOnError=false
154 }
155 
156 
157 bool Foam::Switch::contains(const std::string& str)
158 {
159  return (switchType::INVALID != parse(str, false)); // failOnError=false
160 }
161 
162 
164 (
165  const word& key,
166  const dictionary& dict,
167  const Switch deflt
168 )
169 {
170  return dict.getOrDefault<Switch>(key, deflt, keyType::LITERAL);
171 }
172 
173 
175 (
176  const word& key,
177  dictionary& dict,
178  const Switch deflt
179 )
180 {
181  return dict.getOrAdd<Switch>(key, deflt, keyType::LITERAL);
182 }
184 
185 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
186 
187 Foam::Switch::Switch(const std::string& str)
188 :
189  value_(parse(str, true))
190 {}
191 
192 
193 Foam::Switch::Switch(const char* str)
194 :
195  value_(parse(str, true))
196 {}
197 
198 
199 Foam::Switch::Switch(const std::string& str, bool allowBad)
200 :
201  value_(parse(str, !allowBad))
202 {}
203 
204 
205 Foam::Switch::Switch(const char* str, bool allowBad)
206 :
207  value_(parse(str, !allowBad))
208 {}
209 
210 
211 Foam::Switch::Switch(const float val, const float tol)
212 :
213  value_((mag(val) > tol) ? switchType::TRUE : switchType::FALSE)
214 {}
215 
216 
217 Foam::Switch::Switch(const double val, const double tol)
218 :
219  value_((mag(val) > tol) ? switchType::TRUE : switchType::FALSE)
220 {}
221 
222 
223 Foam::Switch::Switch(const token& tok)
224 :
225  value_(switchType::INVALID)
226 {
227  if (tok.good())
228  {
229  if (tok.isBool())
230  {
231  (*this) = tok.boolToken();
232  }
233  else if (tok.isLabel())
234  {
235  (*this) = bool(tok.labelToken());
236  }
237  else if (tok.isWord())
238  {
239  value_ = parse(tok.wordToken(), false); // failOnError=false
240  }
241  }
242 }
243 
244 
246 (
247  const word& key,
248  const dictionary& dict
249 )
250 :
251  value_(switchType::INVALID)
252 {
253  const token tok(dict.get<token>(key, keyType::LITERAL));
254 
255  Switch sw(tok);
256 
257  if (sw.good())
258  {
259  (*this) = sw;
260  }
261  else
262  {
264  << exit(FatalIOError);
265  }
266 }
267 
268 
270 (
271  const word& key,
272  const dictionary& dict,
273  const Switch deflt,
274  const bool warnOnly
275 )
276 :
277  value_(deflt.value_)
278 {
279  token tok;
280 
281  if (dict.readIfPresent<token>(key, tok, keyType::LITERAL))
282  {
283  Switch sw(tok);
284 
285  if (sw.good())
286  {
287  (*this) = sw;
288  }
289  else if (warnOnly)
290  {
292  << "using default " << deflt.c_str() << endl;
293  }
294  else
295  {
297  << exit(FatalIOError);
298  }
299  }
300 }
301 
302 
303 Foam::Switch::Switch(Istream& is)
304 {
305  is >> *this;
306 }
308 
309 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
310 
311 bool Foam::Switch::good() const noexcept
312 {
313  return (value_ < switchType::INVALID);
314 }
315 
316 
318 {
319  return switchType(value_);
320 }
321 
322 
324 {
325  if (value_ < switchType::INVALID)
326  {
327  // Toggle final bit. So NO <-> YES, OFF <-> ON ...
328  value_ ^= 0x1;
329  }
330 }
331 
332 
333 const char* Foam::Switch::c_str() const noexcept
334 {
335  return names[(value_ & 0x0F)];
336 }
337 
338 
339 std::string Foam::Switch::str() const
340 {
341  return names[(value_ & 0x0F)];
342 }
343 
344 
346 (
347  const word& key,
348  const dictionary& dict
349 )
350 {
351  return dict.readIfPresent<Switch>(key, *this, keyType::LITERAL);
352 }
354 
355 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
356 
358 {
359  token tok(is);
360 
361  sw = Switch(tok);
362 
363  if (sw.good())
364  {
365  is.check(FUNCTION_NAME);
366  }
367  else
368  {
370  << exit(FatalIOError);
371  is.setBad();
372  }
373 
374  return is;
375 }
376 
377 
378 Foam::Ostream& Foam::operator<<(Ostream& os, const Switch sw)
379 {
380  os << sw.c_str();
381  return os;
382 }
383 
384 
385 // ************************************************************************* //
void negate() noexcept
Flip the type, so OFF becomes ON, etc.
Definition: Switch.C:319
bool good() const noexcept
True if token is not UNDEFINED or ERROR.
Definition: tokenI.H:507
dictionary dict
bool good() const noexcept
True if the Switch represents a valid enumeration.
Definition: Switch.C:307
bool isWord() const noexcept
Token is word-variant (WORD, DIRECTIVE)
Definition: tokenI.H:711
static bool contains(const std::string &str)
True if there is a switch type corresponding to the given string.
Definition: Switch.C:153
std::string str() const
A string representation of the Switch value.
Definition: Switch.C:335
switchType
Switch enumerations corresponding to common text representations.
Definition: Switch.H:91
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
List of names generated by calling name() for each list item and filtered for matches.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
const char * c_str() const noexcept
A C-string representation of the Switch value.
Definition: Switch.C:329
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:45
const word & wordToken() const
Return const reference to the word contents.
Definition: tokenI.H:729
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
A token holds an item read from Istream.
Definition: token.H:65
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
A simple wrapper around bool so that it can be read as a word: true/false, on/off, yes/no, any/none. Also accepts 0/1 as a string and shortcuts t/f, y/n.
Definition: Switch.H:77
static Switch getOrDefault(const word &key, const dictionary &dict, const Switch deflt=switchType::FALSE)
Construct Switch from dictionary, with default value.
Definition: Switch.C:160
bool boolToken() const
Return boolean token value.
Definition: tokenI.H:531
static Switch getOrAddToDict(const word &key, dictionary &dict, const Switch deflt=switchType::FALSE)
Construct from dictionary, supplying default value so that if the value is not found, it is added into the dictionary.
Definition: Switch.C:171
void setBad()
Set stream state to be &#39;bad&#39;.
Definition: IOstream.H:459
static const char * name(const bool b) noexcept
A string representation of bool as "false" / "true".
Definition: Switch.C:141
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
A class for handling words, derived from Foam::string.
Definition: word.H:63
Istream & operator>>(Istream &, directionInfo &)
String literal.
Definition: keyType.H:82
errorManip< error > abort(error &err)
Definition: errorManip.H:139
constexpr Switch() noexcept
Default construct as false.
Definition: Switch.H:141
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
switchType type() const noexcept
The underlying enumeration value.
Definition: Switch.C:313
const direction noexcept
Definition: Scalar.H:258
bool isBool() const noexcept
Token is BOOL.
Definition: tokenI.H:525
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
T getOrAdd(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX)
Find and return a T, or return the given default value and add it to dictionary. FatalIOError if it i...
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:77
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
label labelToken() const
Return label value.
Definition: tokenI.H:615
bool isLabel() const noexcept
Token is LABEL.
Definition: tokenI.H:599
InfoProxy< token > info() const noexcept
Return info proxy, for printing token information to a stream.
Definition: token.H:1078
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
bool readIfPresent(const word &key, const dictionary &dict)
Update the value of the Switch if it is found in the dictionary.
Definition: Switch.C:342
static Switch find(const std::string &str)
Find switchType for the given string, returning as a Switch that can be tested for good() or bad()...
Definition: Switch.C:147
Namespace for OpenFOAM.
static OS & printTokenError(OS &os, const token &tok)
Definition: Switch.C:59
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...