| Home | Libraries | People | FAQ | More

## Tutorial

### Basic usage

The `tribool` class acts like the built-in `bool` type, but for 3-state boolean logic. The three states are `true`, `false`, and `indeterminate`, where the first two states are equivalent to those of the C++ `bool` type and the last state represents an unknown boolean value (that may be `true` or `false`, we don't know).

The `tribool` class supports conversion from `bool` values and literals along with its own `indeterminate` keyword:

    tribool b(true);
    b = false;
    b = indeterminate;
    tribool b2(b);

`tribool` supports conversions to `bool` for use in conditional statements. The conversion to `bool` will be `true` when the value of the `tribool` is always true, and `false` otherwise. Consequently, the following idiom may be used to determine which of the three states a `tribool` currently holds:

    tribool b = some_operation();
    if (b) {
      // b is true
    }
    else if (!b) {
      // b is false
    }
    else {
      // b is indeterminate
    }

`tribool` supports the 3-state logic operators `!` (negation), `&&` (AND), and `||` (OR), with `bool` and `tribool` values. For instance:

    tribool x = some_op();
    tribool y = some_other_op();
    if (x && y) {
      // both x and y are true
    }
    else if (!(x && y)) {
      // either x or y is false
    }
    else {
      // neither x nor y is false, but we don't know that both are true

      if (x || y) {
        // either x or y is true
      }
    }

Similarly, `tribool` supports 3-state equality comparisons via the operators `==` and `!=`. These operators differ from "normal" equality operators in C++ because they return a `tribool`, because potentially we might not know the result of a comparison (try to compare `true` and `indeterminate`). For instance:

    tribool x(true);
    tribool y(indeterminate);

    assert(x == x); // okay, x == x returns true
    assert(x == true); // okay, can compare tribools and bools

The `indeterminate` keyword (representing the `indeterminate` `tribool` value) doubles as a function to check if the value of a `tribool` is indeterminate, e.g.,

    tribool x = try_to_do_something_tricky();
    if (indeterminate(x)) {
      // value of x is indeterminate
    }
    else {
      // report success or failure of x
    }

All the logical operators and methods of `tribool` are marked as `constexpr` in C++11. It means that `tribool` can be used in compile time expressions:

    constexpr tribool x = (tribool(true) || tribool(indeterminate));
    static_assert(x, "Must be true!");

| Note
Some compilers may have troubles with evaluating `tribool::operator safe_bool()` at compile time.

### Renaming the indeterminate state

Users may introduce additional keywords for the indeterminate value in addition to the implementation-supplied `indeterminate` using the `BOOST_TRIBOOL_THIRD_STATE` macro. For instance, the following macro instantiation (at the global scope) will introduce the keyword `maybe` as a synonym for `indeterminate` (also residing in the `boost` namespace):

    BOOST_TRIBOOL_THIRD_STATE(maybe)
    tribool x = maybe;
    if (maybe(x)) { /* ... */ }

### `tribool` input/output

`tribool` objects may be read from and written to streams by including the `boost/logic/tribool_io.hpp` header in a manner very similar to `bool` values. When the `boolalpha` flag is not set on the input/output stream, the integral values 0, 1, and 2 correspond to `tribool` values `false`, `true`, and `indeterminate`, respectively. When `boolalpha` is set on the stream, arbitrary strings can be used to represent the three values, the default being "false", "true", and "indeterminate". For instance:

    tribool x;
    cin >> x; // Type "0", "1", or "2" to get false, true, or indeterminate
    cout << boolalpha << x; // Produces "false", "true", or "indeterminate"

`tribool` input and output is sensitive to the stream's current locale. The strings associated with false and true values are contained in the standard `std::numpunct` facet, and the string naming the indeterminate type is contained in the `indeterminate_name` facet. To replace the name of the indeterminate state, you need to imbue your stream with a local containing a `indeterminate_name` facet, e.g.:

    BOOST_TRIBOOL_THIRD_STATE(maybe)
    locale global;
    locale test_locale(global, new indeterminate_name<char>("maybe"));
    cout.imbue(test_locale);
    tribool x(maybe);
    cout << boolalpha << x << endl; // Prints "maybe"

If you C++ standard library implementation does not support locales, `tribool` input/output will still work, but you will be unable to customize the strings printed/parsed when `boolalpha` is set.