mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
bool and Switch reworked
- Switch now stores its value as an unsigned char, which gives it the same storage requirement as bool (1 byte). The original implementation had both bool+word (1+XXX bytes storage), an intermediate version with bool+enum had 8 bytes (1+4 + boundary alignment). - The reading code in boolIO.C and SwitchIO.C is now identical except for the error message. This allows Switch to accept '1', '0' as logical values, and allows bool to accept 'yes', 'no' etc. as logical values. - The Switch text translation of a bool value is now true/false instead of on/off. This is partly personal preference, but we could also output the same text when writing a bool value to Ostream. - Switch gets null and integer constructors so it feels more like bool. Added Switch::operator=(const bool); - Low-level types can be used for the constructors, and low-level return values are used for the greatest flexibility (and speed). - Fixed bugginess with dictionary lookup. The previous version actually used a bool instead of a Switch and bombed on 'on/off'. TODO? perhaps don't worry about the error message and just call the Switch routines from bool.
This commit is contained in:
@ -31,7 +31,7 @@ License
|
|||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
// NB: values chosen such that bitwise '&' 0x1 yields the bool value
|
// NB: values chosen such that bitwise '&' 0x1 yields the bool value
|
||||||
|
// INVALID is also evaluates to false, but don't rely on that
|
||||||
const char* Foam::Switch::names[Foam::Switch::INVALID+1] =
|
const char* Foam::Switch::names[Foam::Switch::INVALID+1] =
|
||||||
{
|
{
|
||||||
"false", "true",
|
"false", "true",
|
||||||
@ -44,24 +44,31 @@ const char* Foam::Switch::names[Foam::Switch::INVALID+1] =
|
|||||||
|
|
||||||
// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::Switch::switchType Foam::Switch::asEnum(const bool val)
|
||||||
|
{
|
||||||
|
return val ? Switch::FALSE : Switch::TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
Foam::Switch::switchType Foam::Switch::asEnum
|
|
||||||
|
Foam::Switch::switchType
|
||||||
|
Foam::Switch::asEnum
|
||||||
(
|
(
|
||||||
const word& val,
|
const std::string& str,
|
||||||
const bool ignoreError
|
const bool allowInvalid
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
for (int sw = 0; sw < INVALID; sw++)
|
for (int sw = 0; sw < Switch::INVALID; sw++)
|
||||||
{
|
{
|
||||||
if (val == names[sw])
|
if (str == names[sw])
|
||||||
{
|
{
|
||||||
if (sw == NO_1)
|
// convert y/n to yes/no (perhaps should deprecate y/n)
|
||||||
|
if (sw == Switch::NO_1)
|
||||||
{
|
{
|
||||||
return NO;
|
return Switch::NO;
|
||||||
}
|
}
|
||||||
else if (sw == YES_1)
|
else if (sw == Switch::YES_1)
|
||||||
{
|
{
|
||||||
return YES;
|
return Switch::YES;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -70,10 +77,10 @@ Foam::Switch::switchType Foam::Switch::asEnum
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ignoreError)
|
if (!allowInvalid)
|
||||||
{
|
{
|
||||||
FatalErrorIn("Switch::asEnum(const word&)")
|
FatalErrorIn("Switch::asEnum(const std::string&)")
|
||||||
<< "unknown switch word " << val
|
<< "unknown switch word " << str << nl
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,47 +88,41 @@ Foam::Switch::switchType Foam::Switch::asEnum
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Switch::switchType Foam::Switch::asEnum(const bool val)
|
bool Foam::Switch::asBool(const switchType sw)
|
||||||
{
|
{
|
||||||
return val ? ON : OFF;
|
return (sw & 0x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::Switch::asBool
|
bool Foam::Switch::asBool
|
||||||
(
|
(
|
||||||
const word& val,
|
const std::string& str,
|
||||||
const bool ignoreError
|
const bool allowInvalid
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
switchType sw = asEnum(val, true);
|
// allow invalid values, but catch after for correct error message
|
||||||
|
switchType sw = asEnum(str, true);
|
||||||
|
|
||||||
// catch error here
|
if (sw == Switch::INVALID && !allowInvalid)
|
||||||
if (sw == INVALID && !ignoreError)
|
|
||||||
{
|
{
|
||||||
FatalErrorIn("Switch::asBool(const word&)")
|
FatalErrorIn("Switch::asBool(const std::string&)")
|
||||||
<< "unknown switch word " << val
|
<< "unknown switch word " << str << nl
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
return asBool(sw);
|
return (sw & 0x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::Switch::asBool(const switchType& val)
|
const char* Foam::Switch::asText(const bool b)
|
||||||
{
|
{
|
||||||
return (val & 0x1);
|
return b ? names[Switch::TRUE] : names[Switch::FALSE];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::word Foam::Switch::asWord(const bool val)
|
const char* Foam::Switch::asText(const switchType sw)
|
||||||
{
|
{
|
||||||
return word((val ? names[ON] : names[OFF]), false);
|
return names[sw];
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::word Foam::Switch::asWord(const switchType& val)
|
|
||||||
{
|
|
||||||
return word(names[val], false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -140,7 +141,7 @@ Foam::Switch Foam::Switch::lookupOrAddToDict
|
|||||||
|
|
||||||
bool Foam::Switch::readIfPresent(const word& name, const dictionary& dict)
|
bool Foam::Switch::readIfPresent(const word& name, const dictionary& dict)
|
||||||
{
|
{
|
||||||
return dict.readIfPresent(name, bool_);
|
return dict.readIfPresent<Switch>(name, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ Class
|
|||||||
|
|
||||||
Description
|
Description
|
||||||
A simple wrapper around bool so that it can be read as a word:
|
A simple wrapper around bool so that it can be read as a word:
|
||||||
on/off, true/false, yes/no or y/n.
|
true/false, on/off, yes/no or y/n.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
Switch.C
|
Switch.C
|
||||||
@ -61,19 +61,28 @@ class dictionary;
|
|||||||
|
|
||||||
class Switch
|
class Switch
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- The logic and enumerated text representation stored as a single byte
|
||||||
|
unsigned char switch_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- The various text representations for a switch value.
|
// Public data types
|
||||||
enum switchType
|
|
||||||
{
|
//- The various text representations for a switch value.
|
||||||
FALSE = 0, TRUE = 1,
|
// These also correspond to the entries in names.
|
||||||
OFF = 2, ON = 3,
|
enum switchType
|
||||||
NO = 4, YES = 5,
|
{
|
||||||
NO_1 = 6, YES_1 = 7,
|
FALSE = 0, TRUE = 1,
|
||||||
INVALID
|
OFF = 2, ON = 3,
|
||||||
};
|
NO = 4, YES = 5,
|
||||||
|
NO_1 = 6, YES_1 = 7,
|
||||||
|
INVALID
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Static data members
|
// Static data members
|
||||||
|
|
||||||
@ -81,49 +90,68 @@ private:
|
|||||||
// Includes an extra entry for "invalid".
|
// Includes an extra entry for "invalid".
|
||||||
static const char* names[INVALID+1];
|
static const char* names[INVALID+1];
|
||||||
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Enumerated string representation
|
// Static Member Functions
|
||||||
switchType switch_;
|
|
||||||
|
|
||||||
//- The boolean value
|
|
||||||
bool bool_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Private member functions
|
|
||||||
|
|
||||||
//- Return a switchType representation of a bool
|
//- Return a switchType representation of a bool
|
||||||
static switchType asEnum(const bool);
|
static switchType asEnum(const bool);
|
||||||
|
|
||||||
//- Return a switchType representation of a word
|
//- Return a switchType representation of a word
|
||||||
static switchType asEnum(const word&, const bool ignoreError=false);
|
// Optionally allow bad words, and catch the error elsewhere
|
||||||
|
static switchType asEnum
|
||||||
//- Return a bool representation of a word
|
(
|
||||||
static bool asBool(const word&, const bool ignoreError=false);
|
const std::string&,
|
||||||
|
const bool allowInvalid=false
|
||||||
|
);
|
||||||
|
|
||||||
//- Return a bool representation of a switchType
|
//- Return a bool representation of a switchType
|
||||||
static bool asBool(const switchType&);
|
static bool asBool(const switchType);
|
||||||
|
|
||||||
//- Return a word representation of a bool value
|
//- Return a bool representation of a word
|
||||||
static word asWord(const bool);
|
// Optionally allow bad words, and catch the error elsewhere
|
||||||
|
static bool asBool
|
||||||
|
(
|
||||||
|
const std::string&,
|
||||||
|
const bool allowInvalid=false
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Return a text representation of a bool value
|
||||||
|
static const char* asText(const bool);
|
||||||
|
|
||||||
|
//- Return a text representation of a switchType
|
||||||
|
static const char* asText(const switchType);
|
||||||
|
|
||||||
//- Return a word representation of a switchType
|
|
||||||
static word asWord(const switchType&);
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct null as false
|
||||||
|
Switch()
|
||||||
|
:
|
||||||
|
switch_(Switch::FALSE)
|
||||||
|
{}
|
||||||
|
|
||||||
//- Construct from bool
|
//- Construct from bool
|
||||||
Switch(const bool value)
|
Switch(const bool value)
|
||||||
:
|
:
|
||||||
switch_(asEnum(value)),
|
switch_(asEnum(value))
|
||||||
bool_(value)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//- Construct from word
|
//- Construct from integer values (treats integer as bool value)
|
||||||
Switch(const word& value)
|
Switch(const int value)
|
||||||
:
|
:
|
||||||
switch_(asEnum(value)),
|
switch_(asEnum(bool(value)))
|
||||||
bool_(asBool(switch_))
|
{}
|
||||||
|
|
||||||
|
//- Construct from std::string, string, word
|
||||||
|
Switch(const std::string& value)
|
||||||
|
:
|
||||||
|
switch_(asEnum(value))
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Construct from character array
|
||||||
|
Switch(const char* value)
|
||||||
|
:
|
||||||
|
switch_(asEnum(std::string(value)))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//- Construct from Istream
|
//- Construct from Istream
|
||||||
@ -141,23 +169,17 @@ public:
|
|||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
|
|
||||||
Switch& operator=(const Switch& rhs)
|
//- Conversion to bool
|
||||||
{
|
|
||||||
switch_ = rhs.switch_;
|
|
||||||
bool_ = rhs.bool_;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator bool() const
|
operator bool() const
|
||||||
{
|
{
|
||||||
return bool_;
|
return (switch_ & 0x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// operator const word&() const
|
//- Assignment from bool
|
||||||
// {
|
void operator=(const bool b)
|
||||||
// return asWord(switch_);
|
{
|
||||||
// }
|
switch_ = (b ? Switch::TRUE : Switch::FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Member fuctions
|
// Member fuctions
|
||||||
|
|||||||
@ -39,11 +39,49 @@ Foam::Switch::Switch(Istream& is)
|
|||||||
|
|
||||||
Foam::Istream& Foam::operator>>(Istream& is, Switch& s)
|
Foam::Istream& Foam::operator>>(Istream& is, Switch& s)
|
||||||
{
|
{
|
||||||
word w(is);
|
token t(is);
|
||||||
|
|
||||||
s.switch_ = Switch::asEnum(w);
|
if (!t.good())
|
||||||
s.bool_ = Switch::asBool(s.switch_);
|
{
|
||||||
|
is.setBad();
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t.isLabel())
|
||||||
|
{
|
||||||
|
s.switch_ = Switch::asEnum(bool(t.labelToken()));
|
||||||
|
}
|
||||||
|
else if (t.isWord())
|
||||||
|
{
|
||||||
|
// allow invalid values, but catch after for correct error message
|
||||||
|
Switch::switchType sw = Switch::asEnum(t.wordToken(), true);
|
||||||
|
|
||||||
|
if (sw == Switch::INVALID)
|
||||||
|
{
|
||||||
|
is.setBad();
|
||||||
|
FatalIOErrorIn("operator>>(Istream&, Switch&)", is)
|
||||||
|
<< "expected 'true/false', 'on/off' ... found " << t.wordToken()
|
||||||
|
<< exit(FatalIOError);
|
||||||
|
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.switch_ = sw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is.setBad();
|
||||||
|
FatalIOErrorIn("operator>>(Istream&, bool/Switch&)", is)
|
||||||
|
<< "wrong token type - expected bool found " << t
|
||||||
|
<< exit(FatalIOError);
|
||||||
|
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check state of Istream
|
||||||
is.check("Istream& operator>>(Istream&, Switch&)");
|
is.check("Istream& operator>>(Istream&, Switch&)");
|
||||||
|
|
||||||
return is;
|
return is;
|
||||||
@ -52,7 +90,7 @@ Foam::Istream& Foam::operator>>(Istream& is, Switch& s)
|
|||||||
|
|
||||||
Foam::Ostream& Foam::operator<<(Ostream& os, const Switch& s)
|
Foam::Ostream& Foam::operator<<(Ostream& os, const Switch& s)
|
||||||
{
|
{
|
||||||
os << Switch::names[s.switch_];
|
os << Switch::names[s.switch_];
|
||||||
os.check("Ostream& operator<<(Ostream&, const Switch&)");
|
os.check("Ostream& operator<<(Ostream&, const Switch&)");
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,9 +22,6 @@ License
|
|||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
Description
|
|
||||||
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "bool.H"
|
#include "bool.H"
|
||||||
@ -32,8 +29,8 @@ Description
|
|||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
const char* const Foam::pTraits<bool>::typeName = "bool";
|
const char* const Foam::pTraits<bool>::typeName = "bool";
|
||||||
const bool Foam::pTraits<bool>::zero = 0;
|
const bool Foam::pTraits<bool>::zero(false);
|
||||||
const bool Foam::pTraits<bool>::one = 1;
|
const bool Foam::pTraits<bool>::one(true);
|
||||||
|
|
||||||
const char* Foam::pTraits<bool>::componentNames[] = { "x" };
|
const char* Foam::pTraits<bool>::componentNames[] = { "x" };
|
||||||
|
|
||||||
|
|||||||
@ -77,7 +77,7 @@ public:
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
dim = 3, // Dimensionality of space
|
dim = 3, // Dimensionality of space
|
||||||
rank = 0, // Rank od bool is 0
|
rank = 0, // Rank of bool is 0
|
||||||
nComponents = 1 // Number of components in bool is 1
|
nComponents = 1 // Number of components in bool is 1
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ public:
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct from Istream
|
//- Construct from Istream
|
||||||
pTraits(Istream& is);
|
pTraits(Istream&);
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
|
|||||||
@ -32,12 +32,25 @@ Description
|
|||||||
#include "error.H"
|
#include "error.H"
|
||||||
|
|
||||||
#include "bool.H"
|
#include "bool.H"
|
||||||
|
#include "Switch.H"
|
||||||
#include "IOstreams.H"
|
#include "IOstreams.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::Istream& Foam::operator>>(Istream& is, bool& b)
|
Foam::Istream& Foam::operator>>(Istream& is, bool& b)
|
||||||
{
|
{
|
||||||
|
// we could also process everything via Switch
|
||||||
|
// The error messages are the problem: they are from SwitchIO.C
|
||||||
|
// Switch sw(is);
|
||||||
|
//
|
||||||
|
// if (is.good())
|
||||||
|
// {
|
||||||
|
// b = sw;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return is;
|
||||||
|
//
|
||||||
|
//
|
||||||
token t(is);
|
token t(is);
|
||||||
|
|
||||||
if (!t.good())
|
if (!t.good())
|
||||||
@ -52,29 +65,27 @@ Foam::Istream& Foam::operator>>(Istream& is, bool& b)
|
|||||||
}
|
}
|
||||||
else if (t.isWord())
|
else if (t.isWord())
|
||||||
{
|
{
|
||||||
// use Switch asBool() here?
|
// allow invalid values, but catch after for correct error message
|
||||||
if (t.wordToken() == "true" || t.wordToken() == "on")
|
Switch::switchType sw = Switch::asEnum(t.wordToken(), true);
|
||||||
{
|
|
||||||
b = true;
|
if (sw == Switch::INVALID)
|
||||||
}
|
|
||||||
else if (t.wordToken() == "false" || t.wordToken() == "off")
|
|
||||||
{
|
|
||||||
b = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
is.setBad();
|
is.setBad();
|
||||||
FatalIOErrorIn("operator>>(Istream&, bool&)", is)
|
FatalIOErrorIn("operator>>(Istream&, bool&)", is)
|
||||||
<< "expected 'true' or 'false', found " << t.wordToken()
|
<< "expected 'true/false', 'on/off', found " << t.wordToken()
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
|
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b = Switch::asBool(sw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
is.setBad();
|
is.setBad();
|
||||||
FatalIOErrorIn("operator>>(Istream&, bool&)", is)
|
FatalIOErrorIn("operator>>(Istream&, bool/Switch&)", is)
|
||||||
<< "wrong token type - expected bool found " << t
|
<< "wrong token type - expected bool found " << t
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
|
|
||||||
@ -82,7 +93,6 @@ Foam::Istream& Foam::operator>>(Istream& is, bool& b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Check state of Istream
|
// Check state of Istream
|
||||||
is.check("Istream& operator>>(Istream&, bool&)");
|
is.check("Istream& operator>>(Istream&, bool&)");
|
||||||
|
|
||||||
@ -92,18 +102,21 @@ Foam::Istream& Foam::operator>>(Istream& is, bool& b)
|
|||||||
|
|
||||||
Foam::Ostream& Foam::operator<<(Ostream& os, const bool b)
|
Foam::Ostream& Foam::operator<<(Ostream& os, const bool b)
|
||||||
{
|
{
|
||||||
|
// we could also write as text string without any difficulty
|
||||||
|
// os << Switch::asText(b);
|
||||||
os.write(label(b));
|
os.write(label(b));
|
||||||
os.check("Ostream& operator<<(Ostream&, const bool&)");
|
os.check("Ostream& operator<<(Ostream&, const bool)");
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::readBool(Istream& is)
|
bool Foam::readBool(Istream& is)
|
||||||
{
|
{
|
||||||
bool b;
|
bool val;
|
||||||
is >> b;
|
is >> val;
|
||||||
|
|
||||||
return b;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
Reference in New Issue
Block a user