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.

template Flag (
string name
) {}

Members

Enums

Flag
enum Flag

Examples

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".yes and Flag!"Name".no 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 $(LUCKY 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.

Flag!"abc" flag;

assert(flag == Flag!"abc".no);
assert(flag == No.abc);
assert(!flag);
if (flag) assert(0);
auto flag = Yes.abc;

assert(flag);
assert(flag == Yes.abc);
if (!flag) assert(0);
if (flag) {} else assert(0);

Meta

Suggestion Box / Bug Report