We are happy to incorporate content from volunteers!!
Coding Patterns - Dictionary
Dictionary on/off flags.
In many cases, it can be advantageous to enable/disable code
functionality based on a user flag. Unless pretty output is needed,
a plain bool
suffices. Eg,
const bool flag(dict.getOrDefault("flag", false));
If the user flag will also be used for pretty output (eg, on/off,
yes/no), the Switch
class is used:
const Switch flag(dict.getOrDefault<Switch>("flag", false));
Reading dictionary entries
\since 1812
const scalar value(dict.get<scalar>("value"));
const word modelType(dict.get<word>("type"));
const vector dirn(dict.get<vector>("direction"));
- These retrieve values with input checking on type and excess tokens.
Anti-pattern: using dictionary lookup()
returns a stream,
which needs additional handling for primitives and does not incorporate
input checking:
const scalar value(readScalar(dict.lookup("value"));
const word modelType(dict.lookup("type"));
const vector dirn(dict.lookup("direction"));
\since 1812
When reading into existing entries:
dict.readEntry("value", value);
dict.readIfPresent("value", value);
// or
if (dict.readIfPresent("value", value))
{
... more actions
}
Anti-pattern: using raw dictionary lookup()
or doing the
conditionals manually:
dict.lookup("value") >> value;
if (dict.found("value"))
{
dict.lookup("value") >> value;
... more actions
}
Get dictionary values with additional checks
\since 1906
It is possible to embed range or other checks into the dictionary retrieval. The checks take the form of a unary predicate, and there are many, many ways to express them. Only dictionary input values are checked, not any default value supplied by the programmer.
const scalar relax(dict.getCheck<scalar>("relax", scalarMinMax::zero_one()));
const scalar positive(dict.getCheckOrDefault<scalar>("pos", 1, scalarMinMax::ge(SMALL));
const scalar positive(dict.getCheckOrDefault<scalar>("pos", 1, scalarRange::gt0());
const scalar positive(dict.getCheck<label>("pos", labelMinMax::ge(0));
Writing dictionary entries
\since 1606
os.writeEntry("key", value);
Anti-pattern: doing everything yourself is messy and repetitive:
os.writeKeyword("key") << value << token::END_STATEMENT << nl;
Writing sub-dictionary entries
\since 1606
os.beginBlock("entries");
os.writeEntry("key", value);
...
os.endBlock();
Anti-pattern: doing everything yourself:
os.indent();
os.write("entries") << nl;
os.indent();
os << token::BEGIN_BLOCK << nl;
os.incrIndent();
os.writeKeyword("key") << value << token::END_STATEMENT << nl;
...
os.decrIndent();
os.indent();
os << token::END_BLOCK << nl;
Copyright (C) 2019-2020 OpenCFD Ltd.