Douglas Gregor dgregor -at- cs.indiana.edu 2002 2003 2004 Douglas Gregor Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Three-state boolean type Boost.Tribool
Introduction The 3-state boolean library contains a single class, boost::logic::tribool, along with support functions and operator overloads that implement 3-state boolean logic.
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!"); 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)) { /* ... */ }
<code>tribool</code> 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.
Test all features of the boost::logic::tribool class. Test the use of the BOOST_TRIBOOL_THIRD_STATE macro. Test tribool input/output.