Enum std.typecons.Flag
Defines a simple, self-documenting yes/no flag. This makes it easy for
APIs to define functions accepting flags without resorting to bool
, which is opaque in calls, and without needing to define an
enumerated type separately. Using Flag!"Name"
instead of bool
makes the flag's meaning visible in calls. Each yes/no flag has
its own type, which makes confusions and mix-ups impossible.
enum Flag(string name)
: bool { ... }
Enum members
Name | Description |
---|---|
no
|
When creating a value of type Flag!"Name" , use Flag!"Name" for the negative option. When using a value
of type Flag!"Name" , compare it against Flag!"Name" or just false or 0 .
|
yes
|
When creating a value of type Flag!"Name" , use Flag!"Name" for the affirmative option. When using a
value of type Flag!"Name" , compare it against Flag!"Name" .
|
Example
Code calling getLine
(usually far away from its definition) can't be
understood without looking at the documentation, even by users familiar with
the API:
string getLine(bool keepTerminator)
{
...
if (keepTerminator) ...
...
}
...
auto line = getLine(false);
Assuming the reverse meaning (i.e. "ignoreTerminator") and inserting the wrong code compiles and runs with erroneous results.
After replacing the boolean parameter with an instantiation of Flag
, code
calling getLine
can be easily read and understood even by people not
fluent with the API:
string getLine(Flag!"keepTerminator" keepTerminator)
{
...
if (keepTerminator) ...
...
}
...
auto line = getLine(Yes .keepTerminator);
The structs Yes
and No
are provided as shorthand for
Flag!"Name"
and Flag!"Name"
and are preferred for brevity and
readability. These convenience structs mean it is usually unnecessary and
counterproductive to create an alias of a Flag
as a way of avoiding typing
out the full type while specifying the affirmative or negative options.
Passing categorical data by means of unstructured bool
parameters is classified under "simple-data coupling" by Steve
McConnell in the Code Complete book, along with three other
kinds of coupling. The author argues citing several studies that
coupling has a negative effect on code quality. Flag
offers a
simple structuring method for passing yes/no flags to APIs.
Example
Flag!"abc" flag;
writeln(flag); // Flag!"abc".no
writeln(flag); // No.abc
assert(!flag);
if (flag) assert(0);
Example
auto flag = Yes .abc;
assert(flag);
writeln(flag); // Yes.abc
if (!flag) assert(0);
if (flag) {} else assert(0);
Authors
Andrei Alexandrescu, Bartosz Milewski, Don Clugston, Shin Fujishiro, Kenji Hara