Skip to content
Commit Detail

Commit 21e08b5

Author
Harris Hancock <harris@cloudflare.com> 2025-07-11 17:39:15 +0100
Parents
250d4b4
Tree
28d07c4
[nfc] Add WD_STRONG_BOOL() macro

This commit defines a macro which allows us to define "strong boolean" types. In particular, these types never implicitly convert to or from `bool`, or each other. This allows for greater type safety, especially in places where functions accept multiple `bool` parameters right next to each other. The call sites of such functions are notoriously difficult to maintain, as switching the order of two `bool` parameters will change the semantics of every call site, but will not introduce any compilation failures to alert you to the change.

A common way to define a strong boolean is to use an `enum class Foo: bool { NO, YES }` type. That pattern is a big improvement in terms of type safety over standard booleans. It has a couple flaws, however:

- Contextual boolean conversion is impossible
- Uninitialized values remain possible

The lack of contextual boolean conversion is a significant pain point preventing our adoption -- no one wants to write `if (foo == Foo::YES)` where they would normally just write `if (foo)`. The uninitialized value issue is not a disadvantage over regular booleans, but is unfortunate.

This commit introduces a macro, WD_STRONG_BOOL(T), which defines a more ergonomic strong bool than the `enum class` pattern can provide. The resulting types provide:

- Two nested constants, `NO` and `YES`, to be used as "literals"
- Contextual boolean conversion
- Explicit conversion to/from booleans
- Protection against uninitialized values
- Type-preserving logical operators
- Comparison operators via the spaceship operator
- KJ stringification support

Files changed

3 files changed+2 added~1 modified