diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2
new file mode 100644
index 0000000..1e638c2
--- /dev/null
+++ b/doc/Jamfile.v2
@@ -0,0 +1,9 @@
+project boost-sandbox/utility/doc ;
+import boostbook ;
+import doxygen ;
+
+doxygen reference : ../../../boost/logic/tribool.hpp
+ ../../../boost/logic/tribool_fwd.hpp
+ ../../../boost/logic/tribool_io.hpp
+ ;
+boostbook tribool : tribool.boostbook ;
diff --git a/doc/tribool.boostbook b/doc/tribool.boostbook
new file mode 100644
index 0000000..0840d8f
--- /dev/null
+++ b/doc/tribool.boostbook
@@ -0,0 +1,216 @@
+
+
+
+
+
+ Douglas
+ Gregor
+ gregod@cs.rpi.edu
+
+
+
+ 2002
+ 2003
+ 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
+
+
+
+
+ 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
+}
+
+
+
+ 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.
+
+
+
+
+
+
+
+
+ Test all features of the
+ boost::logic::tribool
+ class.
+
+
+
+ Test the use of the
+ BOOST_TRIBOOL_THIRD_STATE
+ macro.
+
+
+
+ Test tribool input/output.
+
+
+
\ No newline at end of file
diff --git a/test/Jamfile b/test/Jamfile
new file mode 100644
index 0000000..ac5ec21
--- /dev/null
+++ b/test/Jamfile
@@ -0,0 +1,35 @@
+# Tribool library
+
+# Copyright (C) 2002-2003 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)
+
+# For more information, see http://www.boost.org/
+
+
+# Testing Jamfile autogenerated from XML source
+subproject libs/logic/test ;
+
+# bring in rules for testing
+SEARCH on testing.jam = $(BOOST_BUILD_PATH) ;
+include testing.jam ;
+
+# Make tests run by default.
+DEPENDS all : test ;
+
+{
+ # look in BOOST_ROOT for sources first, just in this Jamfile
+ local SEARCH_SOURCE = $(BOOST_ROOT) $(SEARCH_SOURCE) ;
+
+ test-suite logic
+ :
+ [ run libs/logic/test/tribool_test.cpp : : : : ]
+
+ [ run libs/logic/test/tribool_rename_test.cpp : : : : ]
+
+ [ run libs/logic/test/tribool_io_test.cpp : : : : ]
+ ;
+}
+
\ No newline at end of file
diff --git a/test/tribool_io_test.cpp b/test/tribool_io_test.cpp
new file mode 100644
index 0000000..a7ff77c
--- /dev/null
+++ b/test/tribool_io_test.cpp
@@ -0,0 +1,178 @@
+// Copyright Doug Gregor 2002-2003. 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)
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+int test_main(int, char*[])
+{
+ using namespace boost::logic;
+
+ tribool x;
+
+ // Check tribool output
+ std::ostringstream out;
+
+ // Output false (noboolalpha)
+ out.str(std::string());
+ x = false;
+ out << x;
+ std::cout << "Output false (noboolalpha): " << out.str() << std::endl;
+ BOOST_TEST(out.str() == "0");
+
+ // Output true (noboolalpha)
+ out.str(std::string());
+ x = true;
+ out << x;
+ std::cout << "Output true (noboolalpha): " << out.str() << std::endl;
+ BOOST_TEST(out.str() == "1");
+
+ // Output indeterminate (noboolalpha)
+ out.str(std::string());
+ x = indeterminate;
+ out << x;
+ std::cout << "Output indeterminate (noboolalpha): " << out.str()
+ << std::endl;
+ BOOST_TEST(out.str() == "2");
+
+ const std::numpunct& punct =
+ BOOST_USE_FACET(std::numpunct, out.getloc());
+
+ // Output false (boolalpha)
+ out.str(std::string());
+ x = false;
+ out << std::boolalpha << x;
+ std::cout << "Output false (boolalpha): " << out.str() << std::endl;
+ BOOST_TEST(out.str() == punct.falsename());
+
+ // Output true (boolalpha)
+ out.str(std::string());
+ x = true;
+ out << std::boolalpha << x;
+ std::cout << "Output true (boolalpha): " << out.str() << std::endl;
+
+ BOOST_TEST(out.str() == punct.truename());
+
+ // Output indeterminate (boolalpha - default name)
+ out.str(std::string());
+ x = indeterminate;
+ out << std::boolalpha << x;
+ std::cout << "Output indeterminate (boolalpha - default name): " << out.str()
+ << std::endl;
+ BOOST_TEST(out.str() == "indeterminate");
+
+#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
+ // No template constructors, so we can't build the test locale
+#else
+ // Give indeterminate a new name, and output it via boolalpha
+ std::locale global;
+ std::locale test_locale(global, new indeterminate_name("maybe"));
+ out.imbue(test_locale);
+ out.str(std::string());
+ out << std::boolalpha << x;
+ std::cout << "Output indeterminate (boolalpha - \"maybe\"): " << out.str()
+ << std::endl;
+ BOOST_TEST(out.str() == "maybe");
+#endif
+
+ // Checking tribool input
+
+ // Input false (noboolalpha)
+ {
+ std::istringstream in("0");
+ std::cout << "Input \"0\" (checks for false)" << std::endl;
+ in >> x;
+ BOOST_TEST(x == false);
+ }
+
+ // Input true (noboolalpha)
+ {
+ std::istringstream in("1");
+ std::cout << "Input \"1\" (checks for true)" << std::endl;
+ in >> x;
+ BOOST_TEST(x == true);
+ }
+
+ // Input false (noboolalpha)
+ {
+ std::istringstream in("2");
+ std::cout << "Input \"2\" (checks for indeterminate)" << std::endl;
+ in >> x;
+ BOOST_TEST(indeterminate(x));
+ }
+
+ // Input bad number (noboolalpha)
+ {
+ std::istringstream in("3");
+ std::cout << "Input \"3\" (checks for failure)" << std::endl;
+ BOOST_TEST(!(in >> x));
+ }
+
+ // Input false (boolalpha)
+ {
+ std::istringstream in("false");
+ std::cout << "Input \"false\" (checks for false)" << std::endl;
+ in >> std::boolalpha >> x;
+ BOOST_TEST(x == false);
+ }
+
+ // Input true (boolalpha)
+ {
+ std::istringstream in("true");
+ std::cout << "Input \"true\" (checks for true)" << std::endl;
+ in >> std::boolalpha >> x;
+ BOOST_TEST(x == true);
+ }
+
+ // Input indeterminate (boolalpha)
+ {
+ std::istringstream in("indeterminate");
+ std::cout << "Input \"indeterminate\" (checks for indeterminate)"
+ << std::endl;
+ in >> std::boolalpha >> x;
+ BOOST_TEST(indeterminate(x));
+ }
+
+ // Input bad string (boolalpha)
+ {
+ std::istringstream in("bad");
+ std::cout << "Input \"bad\" (checks for failure)"
+ << std::endl;
+ BOOST_TEST(!(in >> std::boolalpha >> x));
+ }
+
+#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
+ // No template constructors, so we can't build the test locale
+#else
+
+ // Input indeterminate named "maybe" (boolalpha)
+ {
+ std::istringstream in("maybe");
+ in.imbue(test_locale);
+ std::cout << "Input \"maybe\" (checks for indeterminate, uses locales)"
+ << std::endl;
+ in >> std::boolalpha >> x;
+ BOOST_TEST(indeterminate(x));
+ }
+
+ // Input indeterminate named "true_or_false" (boolalpha)
+ {
+ std::locale my_locale(global,
+ new indeterminate_name("true_or_false"));
+ std::istringstream in("true_or_false");
+ in.imbue(my_locale);
+ std::cout << "Input \"true_or_false\" (checks for indeterminate)"
+ << std::endl;
+ in >> std::boolalpha >> x;
+ BOOST_TEST(indeterminate(x));
+ }
+#endif
+
+ return 0;
+}
diff --git a/test/tribool_rename_test.cpp b/test/tribool_rename_test.cpp
new file mode 100644
index 0000000..6114fc3
--- /dev/null
+++ b/test/tribool_rename_test.cpp
@@ -0,0 +1,123 @@
+// Copyright Doug Gregor 2002-2003. 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)
+
+// For more information, see http://www.boost.org
+
+#include
+#include
+#include
+
+BOOST_TRIBOOL_THIRD_STATE(maybe)
+
+int test_main(int,char*[])
+{
+ using namespace boost::logic;
+
+ tribool x; // false
+ tribool y(true); // true
+ tribool z(maybe); // maybe
+
+ BOOST_TEST(!x);
+ BOOST_TEST(x == false);
+ BOOST_TEST(false == x);
+ BOOST_TEST(x != true);
+ BOOST_TEST(true != x);
+ BOOST_TEST(maybe(x == maybe));
+ BOOST_TEST(maybe(maybe == x));
+ BOOST_TEST(maybe(x != maybe));
+ BOOST_TEST(maybe(maybe != x));
+ BOOST_TEST(x == x);
+ BOOST_TEST(!(x != x));
+ BOOST_TEST(!(x && true));
+ BOOST_TEST(!(true && x));
+ BOOST_TEST(x || true);
+ BOOST_TEST(true || x);
+
+ BOOST_TEST(y);
+ BOOST_TEST(y == true);
+ BOOST_TEST(true == y);
+ BOOST_TEST(y != false);
+ BOOST_TEST(false != y);
+ BOOST_TEST(maybe(y == maybe));
+ BOOST_TEST(maybe(maybe == y));
+ BOOST_TEST(maybe(y != maybe));
+ BOOST_TEST(maybe(maybe != y));
+ BOOST_TEST(y == y);
+ BOOST_TEST(!(y != y));
+
+ BOOST_TEST(maybe(z || !z));
+ BOOST_TEST(maybe(z == true));
+ BOOST_TEST(maybe(true == z));
+ BOOST_TEST(maybe(z == false));
+ BOOST_TEST(maybe(false == z));
+ BOOST_TEST(maybe(z == maybe));
+ BOOST_TEST(maybe(maybe == z));
+ BOOST_TEST(maybe(z != maybe));
+ BOOST_TEST(maybe(maybe != z));
+ BOOST_TEST(maybe(z == z));
+ BOOST_TEST(maybe(z != z));
+
+ BOOST_TEST(!(x == y));
+ BOOST_TEST(x != y);
+ BOOST_TEST(maybe(x == z));
+ BOOST_TEST(maybe(x != z));
+ BOOST_TEST(maybe(y == z));
+ BOOST_TEST(maybe(y != z));
+
+ BOOST_TEST(!(x && y));
+ BOOST_TEST(x || y);
+ BOOST_TEST(!(x && z));
+ BOOST_TEST(maybe(y && z));
+ BOOST_TEST(maybe(z && z));
+ BOOST_TEST(maybe(z || z));
+ BOOST_TEST(maybe(x || z));
+ BOOST_TEST(y || z);
+
+ BOOST_TEST(maybe(y && maybe));
+ BOOST_TEST(maybe(maybe && y));
+ BOOST_TEST(!(x && maybe));
+ BOOST_TEST(!(maybe && x));
+
+ BOOST_TEST(maybe || y);
+ BOOST_TEST(y || maybe);
+ BOOST_TEST(maybe(x || maybe));
+ BOOST_TEST(maybe(maybe || x));
+
+ // Test the if (z) ... else (!z) ... else ... idiom
+ if (z) {
+ BOOST_TEST(false);
+ }
+ else if (!z) {
+ BOOST_TEST(false);
+ }
+ else {
+ BOOST_TEST(true);
+ }
+
+ z = true;
+ if (z) {
+ BOOST_TEST(true);
+ }
+ else if (!z) {
+ BOOST_TEST(false);
+ }
+ else {
+ BOOST_TEST(false);
+ }
+
+ z = false;
+ if (z) {
+ BOOST_TEST(false);
+ }
+ else if (!z) {
+ BOOST_TEST(true);
+ }
+ else {
+ BOOST_TEST(false);
+ }
+
+ std::cout << "no errors detected\n";
+ return 0;
+}
diff --git a/test/tribool_test.cpp b/test/tribool_test.cpp
new file mode 100644
index 0000000..5ef29e7
--- /dev/null
+++ b/test/tribool_test.cpp
@@ -0,0 +1,119 @@
+// Copyright Doug Gregor 2002-2003. 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)
+
+#include
+#include
+#include
+
+int test_main(int, char*[])
+{
+ using namespace boost::logic;
+
+ tribool x; // false
+ tribool y(true); // true
+ tribool z(indeterminate); // indeterminate
+
+ BOOST_TEST(!x);
+ BOOST_TEST(x == false);
+ BOOST_TEST(false == x);
+ BOOST_TEST(x != true);
+ BOOST_TEST(true != x);
+ BOOST_TEST(indeterminate(x == indeterminate));
+ BOOST_TEST(indeterminate(indeterminate == x));
+ BOOST_TEST(indeterminate(x != indeterminate));
+ BOOST_TEST(indeterminate(indeterminate != x));
+ BOOST_TEST(x == x);
+ BOOST_TEST(!(x != x));
+ BOOST_TEST(!(x && true));
+ BOOST_TEST(!(true && x));
+ BOOST_TEST(x || true);
+ BOOST_TEST(true || x);
+
+ BOOST_TEST(y);
+ BOOST_TEST(y == true);
+ BOOST_TEST(true == y);
+ BOOST_TEST(y != false);
+ BOOST_TEST(false != y);
+ BOOST_TEST(indeterminate(y == indeterminate));
+ BOOST_TEST(indeterminate(indeterminate == y));
+ BOOST_TEST(indeterminate(y != indeterminate));
+ BOOST_TEST(indeterminate(indeterminate != y));
+ BOOST_TEST(y == y);
+ BOOST_TEST(!(y != y));
+
+ BOOST_TEST(indeterminate(z || !z));
+ BOOST_TEST(indeterminate(z == true));
+ BOOST_TEST(indeterminate(true == z));
+ BOOST_TEST(indeterminate(z == false));
+ BOOST_TEST(indeterminate(false == z));
+ BOOST_TEST(indeterminate(z == indeterminate));
+ BOOST_TEST(indeterminate(indeterminate == z));
+ BOOST_TEST(indeterminate(z != indeterminate));
+ BOOST_TEST(indeterminate(indeterminate != z));
+ BOOST_TEST(indeterminate(z == z));
+ BOOST_TEST(indeterminate(z != z));
+
+ BOOST_TEST(!(x == y));
+ BOOST_TEST(x != y);
+ BOOST_TEST(indeterminate(x == z));
+ BOOST_TEST(indeterminate(x != z));
+ BOOST_TEST(indeterminate(y == z));
+ BOOST_TEST(indeterminate(y != z));
+
+ BOOST_TEST(!(x && y));
+ BOOST_TEST(x || y);
+ BOOST_TEST(!(x && z));
+ BOOST_TEST(indeterminate(y && z));
+ BOOST_TEST(indeterminate(z && z));
+ BOOST_TEST(indeterminate(z || z));
+ BOOST_TEST(indeterminate(x || z));
+ BOOST_TEST(y || z);
+
+ BOOST_TEST(indeterminate(y && indeterminate));
+ BOOST_TEST(indeterminate(indeterminate && y));
+ BOOST_TEST(!(x && indeterminate));
+ BOOST_TEST(!(indeterminate && x));
+
+ BOOST_TEST(indeterminate || y);
+ BOOST_TEST(y || indeterminate);
+ BOOST_TEST(indeterminate(x || indeterminate));
+ BOOST_TEST(indeterminate(indeterminate || x));
+
+ // Test the if (z) ... else (!z) ... else ... idiom
+ if (z) {
+ BOOST_TEST(false);
+ }
+ else if (!z) {
+ BOOST_TEST(false);
+ }
+ else {
+ BOOST_TEST(true);
+ }
+
+ z = true;
+ if (z) {
+ BOOST_TEST(true);
+ }
+ else if (!z) {
+ BOOST_TEST(false);
+ }
+ else {
+ BOOST_TEST(false);
+ }
+
+ z = false;
+ if (z) {
+ BOOST_TEST(false);
+ }
+ else if (!z) {
+ BOOST_TEST(true);
+ }
+ else {
+ BOOST_TEST(false);
+ }
+
+ std::cout << "no errors detected\n";
+ return 0;
+}