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-2020 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 }
141 
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::found(const std::string& str)
158 {
159  return (switchType::INVALID != parse(str, false)); // failOnError=false
160 }
161 
162 
164 (
165  const word& key,
166  dictionary& dict,
167  const Switch deflt
168 )
169 {
170  return dict.getOrAdd<Switch>(key, deflt, keyType::LITERAL);
171 }
172 
173 
174 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
175 
176 Foam::Switch::Switch(const std::string& str)
177 :
178  value_(parse(str, true))
179 {}
180 
181 
182 Foam::Switch::Switch(const char* str)
183 :
184  value_(parse(str, true))
185 {}
186 
187 
188 Foam::Switch::Switch(const std::string& str, bool allowBad)
189 :
190  value_(parse(str, !allowBad))
191 {}
192 
193 
194 Foam::Switch::Switch(const char* str, bool allowBad)
195 :
196  value_(parse(str, !allowBad))
197 {}
198 
199 
200 Foam::Switch::Switch(const float val, const float tol)
201 :
202  value_((mag(val) > tol) ? switchType::TRUE : switchType::FALSE)
203 {}
204 
205 
206 Foam::Switch::Switch(const double val, const double tol)
207 :
208  value_((mag(val) > tol) ? switchType::TRUE : switchType::FALSE)
209 {}
210 
211 
213 :
214  value_(switchType::INVALID)
215 {
216  if (tok.good())
217  {
218  if (tok.isBool())
219  {
220  (*this) = tok.boolToken();
221  }
222  else if (tok.isLabel())
223  {
224  (*this) = bool(tok.labelToken());
225  }
226  else if (tok.isWord())
227  {
228  value_ = parse(tok.wordToken(), false); // failOnError=false
229  }
230  }
231 }
232 
233 
235 (
236  const word& key,
237  const dictionary& dict
238 )
239 :
240  value_(switchType::INVALID)
241 {
242  const token tok(dict.get<token>(key, keyType::LITERAL));
243 
244  Switch sw(tok);
245 
246  if (sw.good())
247  {
248  (*this) = sw;
249  }
250  else
251  {
253  << exit(FatalIOError);
254  }
255 }
256 
257 
259 (
260  const word& key,
261  const dictionary& dict,
262  const Switch deflt,
263  const bool failsafe
264 )
265 :
266  value_(deflt.value_)
267 {
268  token tok;
269 
271  {
272  Switch sw(tok);
273 
274  if (sw.good())
275  {
276  (*this) = sw;
277  }
278  else if (failsafe)
279  {
281  << "using failsafe " << deflt.c_str() << endl;
282  }
283  else
284  {
286  << exit(FatalIOError);
287  }
288  }
289 }
290 
291 
293 {
294  is >> *this;
295 }
296 
297 
298 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
299 
300 bool Foam::Switch::good() const noexcept
301 {
302  return (value_ < switchType::INVALID);
303 }
304 
305 
307 {
308  return switchType(value_);
309 }
310 
311 
312 void Foam::Switch::negate() noexcept
313 {
314  if (value_ < switchType::INVALID)
315  {
316  // Toggle final bit. So NO <-> YES, OFF <-> ON ...
317  value_ ^= 0x1;
318  }
319 }
320 
321 
322 const char* Foam::Switch::c_str() const noexcept
323 {
324  return names[(value_ & 0x0F)];
325 }
326 
327 
328 std::string Foam::Switch::str() const
329 {
330  return names[(value_ & 0x0F)];
331 }
332 
333 
335 (
336  const word& key,
337  const dictionary& dict
338 )
339 {
340  return dict.readIfPresent<Switch>(key, *this, keyType::LITERAL);
341 }
342 
343 
344 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
345 
347 {
348  token tok(is);
349 
350  sw = Switch(tok);
351 
352  if (sw.good())
353  {
354  is.check(FUNCTION_NAME);
355  }
356  else
357  {
359  << exit(FatalIOError);
360  is.setBad();
361  }
362 
363  return is;
364 }
365 
366 
368 {
369  os << sw.c_str();
370  return os;
371 }
372 
373 
374 // ************************************************************************* //
Foam::token::labelToken
label labelToken() const
Return label value.
Definition: tokenI.H:513
Foam::Switch
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:77
Foam::token::isLabel
bool isLabel() const noexcept
Token is LABEL.
Definition: tokenI.H:497
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::token::isBool
bool isBool() const noexcept
Token is BOOL.
Definition: tokenI.H:423
Foam::dictionary::getOrAdd
T getOrAdd(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX)
Definition: dictionaryTemplates.C:178
Foam::glTF::key
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:108
Foam::token::boolToken
bool boolToken() const
Return boolean token value.
Definition: tokenI.H:429
Foam::FatalIOError
IOerror FatalIOError
Foam::Switch::str
std::string str() const
A string representation of the Switch value.
Definition: Switch.C:328
Foam::operator>>
Istream & operator>>(Istream &, directionInfo &)
Definition: directionInfo.C:230
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::token
A token holds an item read from Istream.
Definition: token.H:68
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:107
Foam::Switch::good
bool good() const noexcept
True if the Switch represents a valid enumeration.
Definition: Switch.C:300
Foam::Switch::find
static Switch find(const std::string &str)
Definition: Switch.C:151
Foam::Switch::readIfPresent
bool readIfPresent(const word &key, const dictionary &dict)
Update the value of the Switch if it is found in the dictionary.
Definition: Switch.C:335
Foam::Switch::found
static bool found(const std::string &str)
Test if there is a switch type corresponding to the given string.
Definition: Switch.C:157
Foam::token::isWord
bool isWord() const noexcept
Token is word-variant (WORD, DIRECTIVE)
Definition: tokenI.H:609
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
error.H
Foam::token::info
InfoProxy< token > info() const
Return info proxy for printing token information to a stream.
Definition: token.H:586
Foam::Switch::INVALID
Definition: Switch.H:94
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::Switch::c_str
const char * c_str() const noexcept
A C-string representation of the Switch value.
Definition: Switch.C:322
Switch.H
Foam::Switch::name
static const char * name(const bool b) noexcept
A string representation of bool as "false" / "true".
Definition: Switch.C:145
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::IOstream::check
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:58
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::printTokenError
static OS & printTokenError(OS &os, const token &tok)
Definition: Switch.C:63
scalar.H
os
OBJstream os(runTime.globalPath()/outputName)
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::token::wordToken
const word & wordToken() const
Return const reference to the word contents.
Definition: tokenI.H:631
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::Switch::type
switchType type() const noexcept
The underlying enumeration value.
Definition: Switch.C:306
Foam::token::good
bool good() const noexcept
True if token is not UNDEFINED or ERROR.
Definition: tokenI.H:405
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
dictionary.H
bool
bool
Definition: EEqn.H:20
Foam::Switch::Switch
constexpr Switch() noexcept
Default construct as false.
Definition: Switch.H:127
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:295
Foam::IOstream::setBad
void setBad()
Set stream state to be 'bad'.
Definition: IOstream.H:369
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::keyType::LITERAL
String literal.
Definition: keyType.H:81
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
IOWarningInFunction
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Definition: messageStream.H:340
Foam::Switch::switchType
switchType
Switch enumerations corresponding to common text representations.
Definition: Switch.H:88
Foam::PtrListOps::names
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Foam::Switch::negate
void negate() noexcept
Flip the type, so OFF becomes ON, etc.
Definition: Switch.C:312
Foam::dictionary::readIfPresent
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:405
Foam::Switch::getOrAddToDict
static Switch getOrAddToDict(const word &key, dictionary &dict, const Switch deflt=switchType::FALSE)
Definition: Switch.C:164