Skip to content

Latest commit

 

History

History
57 lines (41 loc) · 1.83 KB

tagged_bool.md

File metadata and controls

57 lines (41 loc) · 1.83 KB

tagged_bool

This tool is used to avoid naked bools in function parameters.

Normally, if you need two boolean pieces of information to be passed to your function, you could write:

void run(bool engineStarted, bool crewReady);

But this has a number of problems. In the call site, no-one can understand the meaning of the two parameters:

run(false, true);

It is easy to confuse the order of arguments. Also, this works for types other than bool:

run(vec.data(), vec.size()); // a pointer and an int
run(-99.99, +99.99);

Using tagged_bool avoids all these problems. It allows you to easily build your unique bool-like types

#include <ak_toolbox/tagged_bool.hpp>
namespace xplicit = ak_toolkit::xplicit;

using EngineStarted = xplicit::tagged_bool<class EngineStartedTag>;
using CrewReady     = xplicit::tagged_bool<class CrewReadyTag>;

This creates two boolean types: EngineStarted and CrewReady. They can be used as in boolean expressions but are not implicitly convertible from one another, or even bool, and there is no way to construct them form an int or a double or a pointer:

EngineStarted es1 = true;       // error
EngineStarted es2 {vec.data()}; // error
EngineStarted es  {true};       // ok
CrewReady     cr  {false};      // ok
bool ans = cr && !es;           // ok

CrewReady     cr2 {es}          // ok    (explicit conversion)
CrewReady     cr3 = es;         // error (implicit conversion)

Types EngineStartedTag and CrewReadyTag guarantee that different instantiations of tagged_bool render different types. These tags do not have to be complete types.

You declare and use these bool-types as follows:

void set_status(EngineStarted started, CrewReady ready); // function declaration
set_status(EngineStarted{true}, CrewReady{true});        // function call